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

来源:互联网 发布:js@700iiii.cc 编辑:程序博客网 时间:2024/06/05 05:05

描述:

有一个由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 101using 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][n]<<endl;    return 0;}