首先子问题是啥??其实就是要找最右边的加号。上面这段其实就体现了这个子问题。
解题思路:
把在n个数字中插入m个加号的问题化为前i个数字中插入m-1个加号再加上从第i+1个数到第n个数字所组成的数。i的范围是从m一直到n-1,这个范围内取最小值。
这个预处理其实也就是把num二维数组给预处理算出来。
#include<iostream> #include<cstdio> #include<algorithm> using namespace std; const int INF = 99999999; int a[1005],num[1005][1005]; int V(int m,int n) { if(m == 0)//无加号 return num[1][n]; else if(n < m+1)//加号过多 return INF; else { int t = INF; for(int i = m;i <= n-1;i++) t = min(t, V(m-1,i)+num[i+1][n]); return t; } } int main() { int n,m; while(~scanf("%d%d",&n,&m)) { for(int i = 1;i <= n;i++) scanf("%d",&a[i]); //预处理,计算i到j数字串组成的数字 for(int i = 1;i <= n;i++) { num[i][i] = a[i];//只有一个数字,注意num里面两个参数的关系是范围。 for(int j = i+1;j <= n;j++) { num[i][j] = num[i][j-1]*10 + a[j]; } } cout<< V(m,n) <<endl; } return 0; }