您的位置:首页 > 其它

NuptOJ最小代价树——动态规划

2014-06-06 22:14 190 查看

最小代价树

时间限制(普通/Java):1000MS/3000MS 运行内存限制:65536KByte

总提交:272 测试通过:60

描述
以下方法称为最小代价的字母树:给定一正整数序列,例如:4,1,2,3,在不改变数的位置的条件下把它们相加,并且用括号来标记每一次加法所得到的和。

例如:((4+1)+ (2+3))=((5)+(5))=10。除去原数不4,1,2,3之外,其余都为中间结果,如5,5,10,将中间结果相加,得到:5+5+10=20,那么数20称为此数列的一个代价,若得到另一种算法:(4+((1+2)+3))=(4+((3)+3))=(4+(6))=10,数列的另一个代价为:3+6+10=19。若给出N个数,可加N-1对括号,求出此数列的最小代价。

注:结果范围不超出longint.

输入
第一行为数N(1≤N≤200),第二行为N个正整数,整数之间用空格隔开。

输出
输出仅一行,即为最少代价值。

样例输入
4

4 1 2 3
样例输出
19
题目来源
OIBH 模拟赛

分析:DP









#include<stdio.h>

//最小代价树——动态规划

int main()
{
int sum[210] = {0};
__int64 dp[210][210] = {0};
int n;
scanf("%d",&n);
scanf("%d",&sum[1]);
for(int i=2;i<=n;i++)
{
scanf("%d",&sum[i]);
sum[i] += sum[i-1];
dp[i-1][i] = sum[i] - sum[i-2];
}

for(int d=2;d<n;d++)
{
for(int i=1,j=i+d;j<=n;i++,j++)
{
dp[i][j] = 0x7FFFFFFF; // long int(int) 最大值 32bits
for(int k=i;k<j;k++)
{
if(dp[i][j] > dp[i][k]+dp[k+1][j])
dp[i][j] = dp[i][k]+dp[k+1][j];
}
dp[i][j] += sum[j] - sum[i-1]; // 加上前面所有数的和
}
}
printf("%I64d\n",dp[1]
);

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