最大k乘积问题--动态规划

2023-11-20

问题

问题描述:
设x是一个n位十进制整数。如果将x划分为k段,则可得到k个整数。这k个整数的乘积称为x的一个k乘积。试设计一个算法,对于给定的x和k,求出x的最大k乘积。

编程任务:
对于给定的x和k,编程计算x的最大k 乘积。

示例
Sample Input:
请输入整数位数n:4
请输入整数划分位数k:3
请输入4位整数x:1234

Sample Output:
1234的k-1次分割后的最大k乘积是:144


推导过程

将一个n位的数字划分为k段,注意到分为k段是一个多阶段决策测问题,应采用动态规划算法来求解是适宜的。

推导打表过程:

(假设输入4位整数1234划分为3段求最大乘积数)
第一列:表示整数只分一段,结果就是本身。
第二列:表示整数分为两段。
f(2,2)=max{f(1,1)num(1,2)}= max{12}=2;
f(3,2)=max{f(1,1)num(2,3),f(2,1)num(3,3)}=max{123,123}=36;
f(4,2)=max{f(1,1)num(2,3),f(2,1)num(3,4),f(3,1)num(4,4)}=
max{1
234,12
34,123
4}=492;
第三列:表示整数分三段。
f(3,3)=max{f(2,2)num(3,3)}=max{123}=6;
f(4,3)=max{f(2,2)num(3,4),f(3,2)num(4,4)}=max{1234,36
4}=144;

状态转移方程:
f(i,j):表示前i个数分为j段后的最大乘积数。num(i,j)表示第i位开始到第j位的数。一般为了求取f(i,j),求数前i位,设前h个数中已经分成了j-1段,此时最大乘积为(h,j-1)*num(j+1,i)。f(i,j)=max{f(h,j-1)*num(j+1,i)} (j-1<=h<=i-1)

边界条件:
前面i个数字没有进行划分是值显然为前i个数字组成的整数,因而得到边界值为:
f(i,1)=num(1,i) (1<=i<=n)

打印结果乘号:
为了能够打印相应的插入乘号的乘积式,设置标注位置的数组t[j]和c[i][j],其中c[i][j]是为了相应的f[i][j]的第j-1个划分点的位置,而t[j]表明了第j-1个乘号的位置。
当给数组赋值f[i][j]=f[h][j-1]*num(h+1,i)时,做相应赋值c[i][j-1]=h,表明f[i][j]的第j-1个乘号的位置时h。在求得f[n][k]时第k-1个乘号的位置t[k-1]=c[n][k-1]=h的基础上,其他tj可应用t[j]=c[t[j+1]][j]逆推产生。

具体案例实现流程
利用notability实现推导6位数字765438划分为4段求解最大乘积问题
在这里插入图片描述

代码实现:
c++代码:(重点代码有标注**–**)

`#include<iostream>
#include<string>
using namespace std;
string x;//全局变量 

int num(int i,int j)//是为了截取从i开始的长度为j的数字
{
	int sum=0;
	for(int k=i;k<=j;k++)//将字符串转换为相对应的数,如字符串123->数123 
	{
		**sum=sum*10+(x[k-1]-'0');**
	}
	return sum;//返回字符串中所截取到的数 
}

int main()
{
	int n,k;//初始条件输入 
	cout<<"请输入整数位数n:";
	cin>>n;
	cout<<"请输入整数划分位数k:";
	cin>>k;		//n位数被分为k段
	cout<<"请输入"<<n<<"位整数x:";
	cin>>x;		//输入的数
	int f[n+1][k+1];//f[i][j]: 数字的前i位数被分为j段所得到的最大乘积  1/2/34
	int i,j,h;
	int t[k];//建立划分点 
	int c[n][k];
	
	//初始化 
	for(i=1;i<=n;i++)//表示是第一列的内容,数只分为一段,于是这部分的数就是当前内容
	{
		for(j=1;j<=k;j++)
		{
			f[i][j]=0;
		}
		**f[i][1]=num(1,i);//边界条件** 
	}
	//这段 j=1 是不将数字分段,就是前i位数
    //num(1,i)是指截取从第0位到第i-1位的数 
    //(1234:f[1][1]=1,f[2][1]=12,f[3][1]=123,f[4][1]=1234)
    
	for(j=2;j<=k;j++)//分为j段
	{
		for(i=j;i<=n;i++)//前i位数 
		{
			 
			for(h=j-1;h<i;h++)//h为划分点,这是在对前面i个数进行划分,这也只是划分点数的位置,并非是数 
			{
				//f[h][j-1]*num(h+1,i)=前h个数被分为j-1段最大的乘积 *第j段的数(也就是没有并入前h个数的i-h个数) 
				if(f[i][j]<f[h][j-1]*num(h+1,i))//这里是在判断前面 
				{
					**f[i][j]=f[h][j-1]*num(h+1,i)**;//记录当前位置的最大值 
					**c[i][j-1]=h;**	//记录当前求出最大值的断点位置,也就是插入乘号的位置,这个位置是数	
				}
			}
		}	
	}
	
	t[k-1]=c[n][k-1];//记录当前倒数第一个断点位置 
	for(j=k-2;j>=1;j--)//逆推出第j个乘号的位置t[j] 
	{
		**t[j]=c[t[j+1]][j];**//这是在利用后一个断点位置找出前一个断点位置 
	}
	t[0]=0;//t数组没有插入断点,此处赋值是为了后面输出结果 
	t[k]=n;//t数组的k位没有插入断点,此处赋值是为了后面输出结果 
	cout<<endl;
	
	cout<<"划分过程乘积最优子结果内容如下(打表):"<<endl;
	cout<<"i\\j\t";
	for(int z=1;z<=k;z++)
	{
		cout<<z<<"\t";
	} 
	cout<<endl;
	
	for(i=1;i<=n;i++)//输出打表内容,求出最优解 
	{
		cout<<" "<<i<<"\t";
		for(j=1;j<=k;j++)
		{
			cout<<f[i][j]<<"\t";
		}
		cout<<endl;
	}	
	cout<<endl;
	
	cout<<x<<"分成"<<k<<"段后的最大k乘积是:";
	for(j=1;j<=k;j++)//输出最优值的分割内容 
	{	
		**for(int u=t[j-1]+1;u<=t[j];u++)**//输出从一个断点到另一个断点中间的数 
		{
			cout<<x[u-1];	
		}
		if(j<k)//输出乘号做分割 
		{
			cout<<"*";
		}
	}
	//输出最优值 
	cout<<"="<<f[n][k]<<endl;
}`

输出结果测试:
在这里插入图片描述
在这里插入图片描述
添加:
(由于本人是编程小白第一次写blog,文章内容有些优化不足。并且该解法只能解决较简单的最大k乘积问题,不能解决较长的数据,等待更深入的学习后,作者会添加更优的解法,如果有其他大佬有更好的解法欢迎分享!)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

最大k乘积问题--动态规划 的相关文章

  • Mono 无法保存用户设置

    我在 Mono Ubuntu 上保存用户设置时遇到问题 这是代码示例 private void Form1 Load object sender EventArgs e string savedText Properties Setting
  • 添加对共享类的多个 WCF 服务的服务引用

    我正在尝试将我的 WCF Web 服务拆分为几个服务 而不是一个巨大的服务 但是 Visual Studio Silverlight 客户端 复制了两个服务共享的公共类 这是一个简单的例子来说明我的问题 在此示例中 有两个服务 两者都返回类
  • Blazor 与 Razor

    随着 Blazor 的发明 我想知道这两种语言之间是否存在显着的效率 无论是在代码创建方面还是在代码的实际编译 执行方面 https github com SteveSanderson Blazor https github com Ste
  • Linux TUN/TAP:无法从 TAP 设备读回数据

    问题是关于如何正确配置想要使用 Tun Tap 模块的 Linux 主机 My Goal 利用现有的路由软件 以下为APP1和APP2 但拦截并修改其发送和接收的所有消息 由Mediator完成 我的场景 Ubuntu 10 04 Mach
  • 获取从属性构造函数内部应用到哪个属性的成员?

    我有一个自定义属性 在自定义属性的构造函数内 我想将属性的属性值设置为属性所应用到的属性的类型 是否有某种方式可以访问该属性所应用到的成员从我的属性类内部 可以从 NET 4 5 using CallerMemberName Somethi
  • 如何在 VS 中键入时显示方法的完整文档?

    标题非常具有描述性 是否有任何扩展可以让我看到我正在输入的方法的完整文档 我想查看文档 因为我可以在对象浏览器中看到它 其中包含参数的描述和所有内容 而不仅仅是一些 摘要 当然可以选择查看所有覆盖 它可能是智能感知的一部分 或者我不知道它并
  • 在 C# 中将位从 ulong 复制到 long

    所以看来 NET 性能计数器类型 http msdn microsoft com en us library system diagnostics performancecounter aspx有一个恼人的问题 它暴露了long对于计数器
  • 为什么 std::allocator 在 C++17 中丢失成员类型/函数?

    一边看着std 分配器 http en cppreference com w cpp memory allocator 我看到成员 value type pointer const pointer reference const refer
  • Xamarin Android:获取内存中的所有进程

    有没有办法读取所有进程 而不仅仅是正在运行的进程 如果我对 Android 的理解正确的话 一次只有一个进程在运行 其他所有进程都被冻结 后台进程被忽略 您可以使用以下代码片段获取当前正在运行的所有 Android 应用程序进程 Activ
  • 组合框项目为空但数据源已满

    将列表绑定到组合框后 其 dataSource Count 为 5 但组合框项目计数为 0 怎么会这样 我习惯了 Web 编程 而且这是在 Windows 窗体中进行的 所以不行combo DataBind 方法存在 这里的问题是 我试图以
  • C# using 语句、SQL 和 SqlConnection

    使用 using 语句 C SQL 可以吗 private static void CreateCommand string queryString string connectionString using SqlConnection c
  • 如何排列表格中的项目 - MVC3 视图 (Index.cshtml)

    我想使用 ASP NET MVC3 显示特定类型食品样本中存在的不同类型维生素的含量 如何在我的视图 Index cshtml 中显示它 an example 这些是我的代码 table tr th th foreach var m in
  • 在 C 中复制两个相邻字节的最快方法是什么?

    好吧 让我们从最明显的解决方案开始 memcpy Ptr const char a b 2 调用库函数的开销相当大 编译器有时不会优化它 我不会依赖编译器优化 但即使 GCC 很聪明 如果我将程序移植到带有垃圾编译器的更奇特的平台上 我也不
  • 是否有一个 C++ 库可以从 PDF 文件中提取文本,例如 PDFBox for Java? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 去年 我使用 PDFBox 在 Java 中创建了一个应用程序来获取某些 PDF 文件中的原始文本 现在
  • 内核开发和 C++ [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 从我know https stackoverflow com questions 580292 what languages are windo
  • 我应该在应用程序退出之前运行 Dispose 吗?

    我应该在应用程序退出之前运行 Dispose 吗 例如 我创建了许多对象 其中一些对象具有事件订阅 var myObject new MyClass myObject OnEvent OnEventHandle 例如 在我的工作中 我应该使
  • 过度使用委托对性能来说是一个坏主意吗? [复制]

    这个问题在这里已经有答案了 考虑以下代码 if IsDebuggingEnabled instance Log GetDetailedDebugInfo GetDetailedDebugInfo 可能是一个昂贵的方法 因此我们只想在调试模式
  • 为什么 Ajax.BeginForm 在 Chrome 中不起作用?

    我正在使用 c NET MVC2 并尝试创建一个 ajax 表单来调用删除数据库记录 RemoveRelation 的方法 删除记录的过程正在按预期进行 删除记录后 表单应调用一个 JavaScript 函数 从视觉效果中删除该记录 Rem
  • 从类模板参数为 asm 生成唯一的字符串文字

    我有一个非常特殊的情况 我需要为类模板中声明的变量生成唯一的汇编程序名称 我需要该名称对于类模板的每个实例都是唯一的 并且我需要将其传递给asm关键字 see here https gcc gnu org onlinedocs gcc 12
  • 如何使用 std::array 模拟 C 数组初始化“int arr[] = { e1, e2, e3, ... }”行为?

    注意 这个问题是关于不必指定元素数量并且仍然允许直接初始化嵌套类型 这个问题 https stackoverflow com questions 6111565 now that we have stdarray what uses are

随机推荐

  • Springer独立出版

    会议简介 Brief Introduction 2023年触觉与虚拟现实国际会议 ICHVR 2023 会议时间 2023年12月15日 17日 召开地点 中国 北海 大会官网 www ichvr org 2023年触觉与虚拟现实国际会议
  • C++ primer目录

    目录 第1章 快速入门 1 1 编写简单的C 程序 1 2 初窥输入 输出 1 2 1 标准输入与输出对象 1 2 2 一个使用IO库的程序 1 3 关于注释 1 4 控制结构 1 4 1 while语句 1 4 2 for 语句 1 4
  • IT痴汉的工作现状26-好项目,坏项目

    塞翁失马焉知非福 淮南子 人间训 祸兮 福之所倚 福兮 祸之所伏 老子 命运就是这样 当他给你关闭一扇门的同时也为你打开了另一扇门 同样 当他给你打开一扇门的同时也为你关闭了一扇门 有些事情 我们要用辩证的观点去看 人生如此 项目亦如此 伟
  • 数学建模——论文排版

    目录 一 参考文献的排版 1 三种方案 通常使用方案一 方案一有两种方法 2 参考文献排版要点总结 二 附录的排版 具体方法 补充 代码高亮 三 表格标题自动编号 进阶做法 四 公式编辑软件的介绍 1 LaTeX 较难 有时间可学 2 wo
  • AI会议排名_周志华

    AI会议排名 周志华 http blog sina com cn s blog 631a4cc40100xl7d html 南京大学周志华教授写的一个很经典的帖子 不过IJCAI能不能算成是no 1的会议有待商榷 不过总体还算客观 说明 纯
  • Dubbo远程传输协议详解

    前言 上次小编为大家带来了Dubbo调用及容错机制详解 不知道大家有没有去看小编最后留下的问题 欢迎对文章进行评论也希望大家和小编多多交流 今天接着为大家带来Dubbo的内容 传输协议 上次调用机制中并没有涉及Dubbo传输的协议 这次容小
  • 多线程下载文件(支持暂停、取消、断点续传)

    多线程下载文件 支持暂停 取消 断点续传 多线程同时下载文件即 在同一时间内通过多个线程对同一个请求地址发起多个请求 将需要下载的数据分割成多个部分 同时下载 每个线程只负责下载其中的一部分 最后将每一个线程下载的部分组装起来即可 涉及的知
  • 看完这篇 教你玩转渗透测试靶机Vulnhub——HarryPotter:Aragog(1.0.2)

    Vulnhub靶机HarryPotter Aragog渗透测试详解 Vulnhub靶机介绍 Vulnhub靶机下载 Vulnhub靶机安装 Vulnhub靶机漏洞详解 信息收集 漏洞发现 漏洞利用 数据库语句查询 SSH登入 备份文件提权
  • unable to install breakpoint in com... $ $FastClassBySpringCGLIB$ $12fabbfc due to missing line numb

    问题 unable to install breakpoint in com FastClassBySpringCGLIB 12fabbfc due to missing line number attributes Modify comp
  • linux定时执行shell脚本

    一 cron调度进程 c r o n是系统主要的调度进程 可以在无需人工干预的情况下运行作业 有一个叫做 c r o n t a b的命令允许用户提交 编辑或删除相应的作业 每一个用户都可以有一个c r o n t a b文件 来保存调度信
  • 量化投资学习-36:选股的基本方式

    1 选择的总原则 1 强者恒强 热点龙头 2 超跌反弹 星空雷达 2 策略总原则 1 主策略 1 2 辅策略 N 3 候选指标 趋势 支撑线 压力线 短期趋势通道 长期趋势通道 布林线 震荡 MACD底特征 KDJ震荡超卖 9转序列低9 能
  • 4大主流CPU处理器技术架构

    推荐阅读 浅谈linux 内核网络 sk buff 之克隆与复制 深入linux内核架构 进程 线程 了解Docker 依赖的linux内核技术 导读 RISC 精简指令集计算机 是一种执行较少类型计算机指令的微处理器 起源于80年代的MI
  • 【C++】STL中list容器内部元素的移动和交换

    文章目录 前言 一 list是什么 二 元素移动 1 插入 删除 2 切除 拼接 三 元素交换 1 元素值交换 2 元素 节点 交换 总结 前言 提示 list insert list erase list splice std iter
  • 【ESP32】反复重启

    ESP32开发 反复重启 串口输出如下所示 rst 0xc SW CPU RESET boot 0x13 SPI FAST FLASH BOOT configsip 188777542 SPIWP 0xee clk drv 0x00 q d
  • 使用 AJAX,局部刷新 GridView 进行数据绑定的简单实现

    很多用户都有这样需求 比如 点击按钮 刷新 GridView 中的数据 而不是这个页面刷新 使用简单的 XMLHttpRequest 就可以直接实现 具体代码如下 ASPX 代码 lt
  • C语言实现随机发纸牌

    C语言实现随机发纸牌 为避免重复发牌 设二维数组sign 4 13 记载是否发过纸牌 其中行下表表示花色 列下标表示点数 设字符串指针数组card n 存储随机发的n张纸牌 例如card 0 梅花2 按照以下方法以此发出每一张牌 首先产生一
  • Python异常捕获

    在 Python 中 try 和 except 语句用于捕获和处理异常 except 子句可以用来捕获不同类型的异常 Exception 这是 Python 中所有异常的基类 可以捕获几乎所有异常类型 ValueError 当函数收到不适当
  • 使用css 动画实现,水波纹的效果

    每日鸡汤 每个你想要学习的瞬间都是未来的你向自己求救 需求 实现水波纹动画效果 要求中心一个圆点 然后有3个圈 一圈一圈的向里面缩小 说实话我第一个想到了给3个圈设置不同的宽高 然后设置动画0 100 一次缩小宽高 但是 我转念一想 我是不
  • Intellisense and NAnt .build files in VS.NET

    Intellisense and NAnt build files in VS NET This has been blogged about before here and there but I wanted to share it a
  • 最大k乘积问题--动态规划

    问题 问题描述 设x是一个n位十进制整数 如果将x划分为k段 则可得到k个整数 这k个整数的乘积称为x的一个k乘积 试设计一个算法 对于给定的x和k 求出x的最大k乘积 编程任务 对于给定的x和k 编程计算x的最大k 乘积 示例 Sampl