nyoj737石子合并

#include<stdio.h>
#include<string.h>
int min(int a,int b)
{
	return a>b?b:a;
}
int dp[203][203],sum[203]; 
int main()
{
	int n;
	while(~scanf("%d",&n))
	{
        int s[203];
        int i,j,start,end,mid;
        sum[0]=0;
        for(i=1;i<=n;i++)
        {scanf("%d",&s[i]);
        sum[i]=sum[i-1]+s[i];
        dp[i][i]=0;
		}
		for(int count=2;count<=n;count++)//外层循环控制个数 
		   for(start=1;start<=n-count+1;start++)//内层循环控制石子堆移动 
		      {
		      	end=start+count-1;
		      	dp[start][end]=0x3f3f3f3f; 
		      	for(mid=start;mid<end;mid++)
		      	dp[start][end]=min(dp[start][end],dp[start][mid]+dp[mid+1][end]+sum[end]-sum[start-1]);//dp[start][mid]+dp[mid+1][end]是子堆消耗的代价
			  }//+sum[end]-sum[start-1]是本次移动消耗的代价
<pre name="code" class="cpp">		printf("%d\n",dp[1][n]);	
}return 0; }


石子合并是一道关于区间DP的题目,如果能够通过数学原理推出DP方程式的话这道题就不难写出来了 ,通过题意可以看出石子合并就是两个两个的石子堆进行合并需要花费的代价,每次两个相邻的堆进行合并,就需要进行多次循环来控制石子合并的对象和合并的个数;当石子合并时还需要把之前消耗的代价加上。

posted @ 2016-09-27 19:08  考研小黑  阅读(1)  评论(0编辑  收藏  举报