您的位置:首页 > 其它

区间DP——石子合并问题

2015-03-17 18:28 281 查看
述 有N堆石子排成一排,每堆石子有一定的数量。现要将N堆石子并成为一堆。合并的过程只能每次将相邻的两堆石子堆成一堆,每次合并花费的代价为这两堆石子的和,经过N-1次合并后成为一堆。求出总的代价最小值。

输入有多组测试数据,输入到文件结束。
每组测试数据第一行有一个整数n,表示有n堆石子。
接下来的一行有n(0< n <200)个数,分别表示这n堆石子的数目,用空格隔开输出输出总代价的最小值,占单独的一行样例输入31 2 37 13 7 8 16 21 4 18大意:如题意:用一个k记录从是第几次,然后i从1开始到n-k-1结束,j=i+l-1表示,插入m,所以要sum[j]-sum[i-1]O(n^3)代码

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAX = 1000;
const int inf = 9999999;
int dp[MAX][MAX],ans[MAX],sum[MAX],s[MAX][MAX];
int main()
{
int n;
scanf("%d",&n);
memset(dp,0,sizeof(dp));
sum[0] = 0;
for(int i = 1; i <= n ; i++){
scanf("%d",&ans[i]);
sum[i] = sum[i-1] + ans[i];
s[i][i] = i;
}
int k,i,j;
for(int k = 2; k <= n ; k++){
for(int i = 1; i <= n - k + 1;i++){
j = i + k - 1;
dp[i][j] = inf;
for(int m = s[i][j-1]; m <= s[i+1][j];m++){
if(dp[i][j] > dp[i][m]+dp[m+1][j]+sum[j]-sum[i-1]){
dp[i][j] = dp[i][m]+dp[m+1][j]+sum[j]-sum[i-1];
s[i][j] = m;
}
}
}
}
printf("%d\n",dp[1]
);
return 0;
}


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