动态规划4--最佳加法表达式

一、心得

心得:
动态规划因为有递推表达式,所以一定可以写成递推和递归两种写法。
因为递推一定可以写成递归。

区别两种问题:

在10个数字中放任意个加号使得组成的表达式的和最小。
状态转移方程:
将m个加号插入到n个数字组成的数字串中
V(m,n) 表示将m个加号插入到n个数字组成的数字串中组成的表达式和最小的表达式
i表示在第i个数后面插入加号
V(m,n) = Min{ V(m-1,i) + Num(i+1,n) } ( i = m … n-1)
表达式的最后一个加号添加在第 i 个数字后面
这个i要试遍所有的情况

在10个数字中放5个加号使得组成的表达式的和最小。
这就分在哪个位置上面放加号或者不放加号,有点像背包问题
将m个加号插入到n个数字组成的数字串中
V(m,n) = Min{ V(m-1,n-1) , V(m,n-1) }

这里可以把dp中的两维变成1维么,不行,因为看这两维表示的意义
在n个数字中插入m个加号,每一个加号在n个数字中的位置任意

一种是在把m个加号插入n个数字中
循环先m再n
一种是在n个数字中插入m个加号
循环先n再m
都要保证n比m大,n可以取m+1
m写在n前面,n等于m+1,可以省掉一半的情况。写法方便。
i表示插入的位置,位置要在m和n中间
3个加号插入5个数字中间,i的取值3到5????
这个好想:我3个加号插入5个数字中间,最后一个加号的取值肯定要保证之前两个加号最少所需的三个数字

确定递归方程中每一个变量的取值范围实在是重中之重

二、题目及分析

题意:
有一个由1..9组成的数字串.问如果将m个加号插入到这个数字串中,在各种可能形成的表达式中,值最小的那个表达式的值是多少。
输入:
5 3
1 2 3 4 5
输出:
24

假定数字串长度是n,添完加号后,表达式的最后一个加号添加在第 i 个数字后面
那么整个表达式的最小值,就等于在前 i 个数字中插入 m – 1个加号所能形成的最小值,
加上第 i + 1到第 n 个数字所组成的数的值(i从1开始算)。

设V(m,n)表示在n个数字中插入m个加号所能形成
的表达式最小值,那么:
if m = 0
V(m,n) = n个数字构成的整数
else if n < m + 1
V(m,n) = ∞
else
V(m,n) = Min{ V(m-1,i) + Num(i+1,n) } ( i = m … n-1)
Num(i,j)表示从第i个数字到第j个数字所组成的数。数字编号从1开始算。此操作复杂度是O(j-i+1)
总时间复杂度:O(mn2) .(dp二维表已经加号的位置)

三、代码及结果

递推

 1 /*
 2 最佳加法表达式:
 3 题意:
 4 有一个由1..9组成的数字串.问如果将m个加号插入到这个数字串中,在各种可能形成的表达式中,值最小的那个表达式的值是多少。
 5 输入:
 6 5 3
 7 1 2 3 4 5
 8 输出:
 9 24
10
11 */
12 /*
13 预处理和排序都能很好的减少耗时
14 */
15 #include<iostream>
16 #include<cstdio>
17 #include<cstring>
18 #include<algorithm>
19 using namespace std;
20 const int INF=0x3f3f3f3f;
21 const int N=1005;
22 int a[N],num[N][N],dp[N][N];
23 //a[N]里面是存数字串
24 //num[i][j]表示数字串a[N]的第i位到第j位之间的数字串表示的数组
25 //dp[i][j]在i个数字中插入j个加号所能形成的表达式最小值
26 int main(){
27     int n,m;
28     while(scanf("%d %d",&n,&m)){
29         for(int i=1;i<=n;i++){
30             scanf("%d",&a[i]);
31         }
32         //预处理,计算i到j数字串组成的数字
33         for(int i=1;i<=n;i++){
34             num[i][i]=a[i];//只有一个数字
35             for(int j=i+1;j<=n;j++){
36                 num[i][j]=num[i][j-1]*10+a[j];
37             }
38         }
39         memset(dp,0x3f,sizeof(dp));
40         for(int i=1;i<=n;i++){
41             dp[0][i]=num[1][i];//无加号时
42         }
43         //其实就是感觉在那个位置放不放加号
44         //这里n可以写在m前面。要加一个限制条件n>m,好麻烦,所以m在前且n=m+1
45         //这里k的取值范围就是m到n,k表示在第k个数后面插入加号
46         for(int i=1;i<=m;i++)
47             for(int j=i;j<=n;j++)
48                 for(int k=i;k<=j;k++)
49                     dp[i][j]=min(dp[i][j],dp[i-1][k]+num[k+1][j]);
50         cout<<dp[m][n]<<endl;
51     }
52 }
53  

递归

 1 /*
 2 题意:
 3 有一个由1..9组成的数字串.问如果将m个加号插入到这个数字串中,在各种可能形成的表达式中,值最小的那个表达式的值是多少。
 4 输入:
 5 5 3
 6 1 2 3 4 5
 7 输出:
 8 24
 9 子问题:将最后面的那个加号放在第i个数字的后面,计算前i个
10 数字的最佳加法表达式
11 状态:V(m,n)表示在n个数字中插入m个加号所能形成
12 的表达式最小值
13 */
14 //不懂的位置画个实例,会很简单,因为熟悉,所以容易
15 /*
16 心得:
17 动态规划因为有递推表达式,所以一定可以写成递推和递归两种写法。
18 因为递推一定可以写成递归。
19
20 区别两种问题:
21
22 在10个数字中放任意个加号使得组成的表达式的和最小。
23 状态转移方程:
24 将m个加号插入到n个数字组成的数字串中
25 V(m,n) 表示将m个加号插入到n个数字组成的数字串中组成的表达式和最小的表达式
26 i表示在第i个数后面插入加号
27 V(m,n) = Min{ V(m-1,i) + Num(i+1,n) } ( i = m … n-1)
28 表达式的最后一个加号添加在第 i 个数字后面
29 这个i要试遍所有的情况
30
31
32
33 在10个数字中放5个加号使得组成的表达式的和最小。
34 这就分在哪个位置上面放加号或者不放加号,有点像背包问题
35 将m个加号插入到n个数字组成的数字串中
36 V(m,n) = Min{ V(m-1,n-1) , V(m,n-1) }
37
38 这里可以把dp中的两维变成1维么,不行,因为看这两维表示的意义
39 在n个数字中插入m个加号,每一个加号在n个数字中的位置任意
40
41 一种是在把m个加号插入n个数字中
42 循环先m再n
43 一种是在n个数字中插入m个加号
44 循环先n再m
45 都要保证n比m大,n可以取m+1
46 m写在n前面,n等于m+1,可以省掉一半的情况。写法方便。
47 i表示插入的位置,位置要在m和n中间
48 3个加号插入5个数字中间,i的取值3到5????
49 这个好想:我3个加号插入5个数字中间,最后一个加号的取值肯定要保证之前两个加号最少所需的三个数字
50
51 确定递归方程中每一个变量的取值实在是重中之重
52
53 */
54 #include<iostream>
55 #include<cstdio>
56 #include<algorithm>
57 using namespace std;
58 const int INF = 99999999;
59 int a[1005],num[1005][1005];
60 int V(int m,int n)
61 {
62     if(m == 0)//无加号
63         return num[1][n];
64     else if(n < m+1)//加号过多
65         return INF;
66     else
67     {
68         int t = INF;
69         //这里有点像回溯,回溯的话递归里面有循环
70         //说说实话,递归真的很简单,就是把递推公式写进来
71         for(int i = m;i <= n-1;i++) //这里是n减一,排除了最后一个数字后面放加号的情况
72            t = min(t, V(m-1,i)+num[i+1][n]);
73         //不懂的位置画个实例,会很简单,因为熟悉,所以容易
74         return t;
75     }
76 }
77 int main()
78 {
79     int n,m;
80     while(~scanf("%d%d",&n,&m))
81     {
82         for(int i = 1;i <= n;i++)
83             scanf("%d",&a[i]);
84         //预处理,计算i到j数字串组成的数字
85         for(int i = 1;i <= n;i++)
86         {
87             num[i][i] = a[i];//只有一个数字
88             for(int j = i+1;j <= n;j++)
89             {
90                 //这个表达式也可以好好看一下
91                 num[i][j] = num[i][j-1]*10 + a[j];
92             }
93         }
94         cout<< V(m,n) <<endl;
95     }
96     return 0;
97 } 

转载于:https://www.cnblogs.com/Renyi-Fan/p/6970166.html

动态规划4--最佳加法表达式相关推荐

  1. dp 最佳加法表达式

    题意:有一个由1..9组成的数字串.问如果将m个加号插入到这个数字串中,在各种可能形成的表达式中,值最小的那个表达式的值是多少. 分析:假定数字串长度是n,添完加号后,表达式的最后一个加号添加在第i ...

  2. chatgpt赋能python:Python加法表达式,快速简便的计算方式

    Python加法表达式,快速简便的计算方式 介绍 Python是一种可读性强.简洁.易于学习的编程语言,同时也是一种高级编程语言,由于其简洁性和可读性,越来越多的程序员们选择Python作为他们的工作 ...

  3. python中加法表达式_Python自然语言处理练习一

    1.尝试使用Python解释器作为一个计算器,输入表达式,如12/(4+1) >>>12/(4+1) 2 2.26个字母可以组成26的10次方或者26**10个字母长的字符串,也就是 ...

  4. 动态规划 leetcode-714 最佳买卖股票时机含手续费

    1.题目 给定一个整数数组 prices,其中第 i 个元素代表了第 i 天的股票价格 :非负整数 fee 代表了交易股票的手续费用. 你可以无限次地完成交易,但是你每笔交易都需要付手续费.如果你已经 ...

  5. 算法分析与设计「五」动态规划

    文章目录 引例:数字三角形 一.动态规划基本思想 二.动态规划算法基本要素 三.经典题目 题目一:最长上升子序列 题目二:最长公共子序列 题目三:最佳加法表达式 题目四:0-1 背包问题 再讲解动态规 ...

  6. 动态规划常见类型总结

    本文针对动态规划的常见类型进行总结.虽说总结的是动态规划,但顺便把递推也放了进来.严格来说,递推不属于动态规划问题,因为动态规划不仅有递推过程,还要有决策(即取最优),但广义的动态规划是可以包含递推的 ...

  7. 算法基础部分3-动态规划

    算法部分 基础3 一.动态规划的简述   递归到动规的一般转化方法:递归函数有 n 个参数,就定义了一个 n 维数组,数组的下标是递归函数参数的取值范围,数组元素的值是递归函数的返回值,这样就可以从边 ...

  8. 程序设计与算法郭炜老师的课堂笔记2

    程序设计与算法郭炜老师的课堂笔记2 枚举 完美立方 生理周期 称硬币 熄灯问题 递归 求阶乘 汉诺塔 N皇后 逆波兰表达式 表达式求值 上台阶 放苹果 算24 二分算法 找一对数 分治 归并排序 快速 ...

  9. 一元操作符、强制类型转换表达式、乘除操作符、加法操作符、移位操作符、关系操作符、判等操作符、位操作符与逻辑操作符、条件与操作符、条件或操作符--运算机制与返回值

    操作符处理及返回值 先遣提示 一元操作符 前缀递增操作符 ++ 前缀递增操作符 - - 一元加号操作符 + 关于一元数值提升或二元数值提升 可以看这篇博客 一元减号操作符 - 这里涉及了 原码,反码, ...

最新文章

  1. 【转载】关于RabbitMQ的消息确认
  2. Ellipse函数画圆
  3. 为什么我的论文没人引用?
  4. Google的Project Stream准备在Chrome中播放AAA控制台游戏
  5. 具有CDI和lambda的策略模式
  6. procreate 笔刷_插画学习必备:2000款Procreate大师级笔刷,超级强大,免费领取
  7. 《南溪的目标检测学习笔记》——PyTorch模型搭建模板
  8. html自动获取今日的周名称,jquery怎么写显示今天后2周的日历
  9. Spark内核解析之五:Spark Shuffle解析
  10. Android开源项目分类汇总
  11. Scrapy豆瓣电影top250(excel保存和图片下载)
  12. MAC 外接键盘卡顿处理
  13. SystemUI Monkey测试原生代码报错:MLand类NullPointerException
  14. java aes iv_java AES加密解密
  15. 初学者-CSS思维导图(上)
  16. 计算机硬盘改造u盘,iPhone扩容硬盘不要扔!变废为宝!手把手教你如何改装U盘...
  17. Java程序获取和修改.wav音频文件的内部结构
  18. C小程PTA错题集1
  19. android 简单名称混淆,android 混淆基本知识(示例代码)
  20. mysql-front 下载安装

热门文章

  1. 一个Bug能有多大影响:亏损30亿、致6人死亡、甚至差点毁灭世界...
  2. 阿里巴巴为什么不建议直接使用 Async 注解?
  3. Kafka 2.8独立运行,不再需要ZooKeeper
  4. CVPR 2021论文分享会日程公布!
  5. 数据清洗指南完整分享
  6. 你离开学只差这个视频:李宏毅机器学习2020版正式开放上线
  7. Python版本的数据结构书_《用Python解决数据结构与算法问题》
  8. 35岁中年博士失业,决定给后辈一些建议!
  9. 百度研究院:招聘计算机视觉和生物计算方向实习生
  10. 高考623分却说自己是“反面教材”?外卖小哥最新发声!