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

最小代价树

时间限制(普通/Java):1000MS/3000MS          运行内存限制:65536KByte
总提交:272            测试通过:60

描述

以下方法称为最小代价的字母树:给定一正整数序列,例如:4123,在不改变数的位置的条件下把它们相加,并且用括号来标记每一次加法所得到的和。
例如:((4+12+3))=((5+5))=10。除去原数不4123之外,其余都为中间结果,如5510,将中间结果相加,得到: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

NuptOJ最小代价树——动态规划_第1张图片

NuptOJ最小代价树——动态规划_第2张图片

NuptOJ最小代价树——动态规划_第3张图片

NuptOJ最小代价树——动态规划_第4张图片

#include

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

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 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][n]);

	return 0;
}


你可能感兴趣的:(C,C++,ACM)