动态规划基本模型(二)

区间DP

例题:石子合并;

先使用a[i]初始化每个石子的价值

合并n个则需要先合并n-1个 子问题就是合并1~n个的最小值

则合并l长度个的最小值为合并左结点到右结点的最小值;

子问题为每个区间的合并最小值;

使用k枚举每个区间;

则有dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+合并这两段的和)

使用sum[i]初始化每段的价值;

for (int i=1;i<=n;i++)

sum[i]=sum[i]+a[i-1];

则有两段合并的和为右侧结点的sum减去左侧结点的sum 

即sum[j]-sum[i-1];

输出dp[1][n]即可

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
int n;
int a[1001],dp[1001][1001],sum[1001];
int main ()
{
	cin>>n;
	for (int i=1;i<=n;i++)
		cin>>a[i];
	for (int i=1;i<=n;i++)
		sum[i]=sum[i-1]+a[i];
	for (int l=1;l<=n;l++)
	{
		for (int i=1;i<=l;i++)
		{
			int j=i+l-1;
			dp[i][j]=1239813;
			for (int k=i;k<=j;k++)
			{
				dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1]);
			}
		}
	}
	cout<<dp[1][n];
	return 0;	
}


posted @ 2016-11-17 13:53  2000xyy  阅读(189)  评论(0编辑  收藏  举报