51nod oj 1022 石子归并 V2 【环形区间DP----四边形不等式优化】


题目传送门:1022


四边形不等式优化:

m[i,j]=min{m[i,k]+m[k,j]}(s[i,j-1]≤k≤s[i+1,j])


m[i,j]=min{m[i,k]+m[k,j]}(i≤k≤j)

s[i,j]表示i到j的最优分点

s[i,j-1]≤s[i,j]≤s[i+1,j]


怎么证明某一题能不能用这个优化呢--

我---不会---

我就想

对于O( n^3 )算法不行的就假设它能用四边形不等式优化吧---


代码:

#include
#include
#include
using namespace std;
int shu[2020],dp[2020][1010],s[2020][1010],he[2020];
int main()
{
    int n;scanf("%d",&n);
    for (int i=1;i<=n;i++)
    {
        scanf("%d",&shu[i]);
        shu[i+n]=shu[i];
    }
    he[0]=0;
    for (int i=1;i<=2*n;i++)
    he[i]=he[i-1]+shu[i];
    for (int i=1;i<=2*n;i++)  
        for (int j=1;j<=n;j++)  
            dp[i][j]=999999999;  
    for (int i=1;i<=n*2;i++)
    {
    	dp[i][0]=0;
    	dp[i][1]=0;
    	s[i][1]=i;
	}
    for (int k=2;k<=n;k++)
    {
        for (int i=1;i<=n;i++)
        	for (int j=s[i][k-1];j<=s[i+1][k-1];j++)//四边形不等式优化
        		if (dp[i][k]>dp[i][j-i+1]+dp[j+1][k-j+i-1]+he[i+k-1]-he[i-1])
        		{
        			dp[i][k]=dp[i][j-i+1]+dp[j+1][k-j+i-1]+he[i+k-1]-he[i-1];
        			s[i][k]=j;
				}
		for (int i=1;i<=n;i++)
		{
			dp[i+n][k]=dp[i][k];
			s[i+n][k]=s[i][k]+n;
		}
    }
    int ans=666666666;
    for (int i=1;i<=n;i++)
    	ans=min(ans,dp[i][n]);
    printf("%d\n",ans);
    return 0;
}



你可能感兴趣的:(我的ACM成长历程---啦啦啦,区间DP)