您的位置:首页 > 其它

动态规划--(加法表达式)

2017-11-30 17:04 295 查看
描述:

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

输入:
5 3
1 2 3 4 5
输出:
24

设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),可以预处理后存起来。 

#include<iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#define SU 9999999

#define NUM 101
using namespace std;
//递推
int main()
{
int A[100];
int result[2][NUM];//利用滚动数组来解决储存问题;
int num[NUM][NUM];

int n,m;

cin>>n>>m;
for(int i = 1;i<=n;i++)
cin>>A[i];

for(int i = 1;i<=n;i++){
num[i][i] = A[i];
for(int j =i+1;j<=n;j++)
num[i][j] = num[i][j-1]*10 + A[j];
}//将所有的数字存储在数组num中;

// for(int i = 1;i<=n;i++){
// for(int j =1;j<=n;j++)
// cout <<num[i][j]<<" ";
// cout<< endl;
// }//数值的转换测试;

//初始化;
for(int i = 1;i<=n;i++)
result[0][i] = num[1][i];//如果是m= 0;
for(int i = 1;i<=m;i++)
result[i][0] = SU;
result[0][0] = 0;

for(int i = 1;i<=m;i++){//表示加号的个数;
for(int j =1;j<=n;j++){//表示数的个数;
if(i>=n)//加号过多;
result[i%2][j] = SU;
else{
result[i%2][j] = SU;
for(int k = i;k<j;k++)
result[i%2][j] = min(result[i%2][j],result[(i-1)%2][k]+num[k+1][j]);
}
}

// for(int i = 0;i<2;i++){
// for(int j = 0;j<=n;j++)
// printf("%-10d ",result[i][j]);
// cout<<endl;
// }//测试
// cout <<" +++++++++++++++++++++++++++++++"<<endl;
//

}

cout <<result[m%2]
<<endl;

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息