最佳加法表达式(动态规划)
2018-03-02 16:39
453 查看
最佳加法表达式
有一个由1..9组成的数字串.问如果将m个加 号插入到这个数字串中,在各种可能形成的 表达式中,值最小的那个表达式的值是多少输入
1234 212345 3
输出
1924
问题分析
要解决dp类问题,当然是要找子问题,确定目标状态的啦。现在有n个数字组成的数字串,将m个加号插入里面求表达式的最小值。不如我们将其分解为两部分,第m个加号后面最后一项和前m-1个加号所组成的表达式。假设我们将最后一个加号填到了第i个数字后面,那么第i+1->n这一项的值就是可以确定的,那么问题就变成了求将m-1个加号填入到前面i个数字里所组成的表达式的最小值,然后递归去解决。
但是要想一下边界情况喔,当m减到0时,返回的是什么?当然应该是当前状态n个数字所组成的值喽。还有m的上界,一共n个数字,当然加号不能超过n-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(mn^2)
预处理方式
cin>>n>>m; int k = length(n); for(int i = k-1; i >= 0; i--) { s[i] = n%10+'0'; n/=10; } for(int i = 1; i <= k; i++) { num[i][i] = s[i-1]-'0'; for(int j = i+1; j <= k; j++) { num[i][j] = nu c242 m[i][j-1]*10+s[j-1]-'0'; } }
递归方式
int v(int m,int n) { if(m==0) return num[1] ; else if(n<m+1) return 0x3f3f3f3f; else { int min1 = 0x3f3f3f3f; for(int i = m; i <= n-1; i++) min1 = min(v(m-1,i)+num[i+1] ,min1); return min1; } }
递归转递推
memset(dp,0x3f,sizeof dp); for(int i = 1; i <= n; i++)//当没有加号时 dp[0][i] = num[1][i]; for(int i = 1; i <= m; i++) { for(int j = i; j <= n; j++) { for(int l = i; l <= j; l++) dp[i][j] = min(dp[i][j],dp[i-1][l]+num[l+1][j]); } } cout<<dp[m] <<endl;
相关文章推荐
- [PKU暑课笔记] 动态规划(三) 最佳加法表达式 百练2755 POJ3624背包问题
- 动态规划之最佳加法表达式
- 最佳加法表达式(动态规划)
- 最佳加法表达式(动态规划)
- 递推,动态规划(DP),字符串处理,最佳加法表达式
- 动态规划(3):熟练度练习(POJ 1458、最佳加法表达式、bailian2755、POJ3624、bailian1088)
- 动态规划4--最佳加法表达式
- 最佳加法表达式(dp)
- 最佳加法表达式
- 最佳加法表达式
- 最佳加法表达式
- 最佳加法表达式
- dp 最佳加法表达式
- (dp\高精度)最佳加法表达式
- 最佳加法表达式(DP)
- dp 最佳加法表达式
- 最佳加法表达式 dp
- 最佳加法表达式
- 最佳加法表达式 dp
- 最佳加法表达式