四边形不等式 四边形不等式 区间包含 性质 性质2 例题 code

(a<=b<=c<=d)时有(w(a,c)+w(b,d)<=w(a,d)+w(b,c))

也有(w(i,j)+w(i+1,j+1)<=w(i+1,j)+w(i,j+1))

区间包含

(a<=b<=c<=d)时有(w(b,c)<=w(a,d))

性质

(f_{i,j}=min(f_{i,k}+f_{k,j}+w_{i,j}))

如果w满足四边形不等式+区间包含,则f也满足

性质2

(s_{i,j})是[i,j]的决策点k,则有

(s_{i,j-1}<=s_{i,j}<=s_{i+1,j})

例题

hdu3506

破环成链dp,多组数据

code

#include <bits/stdc++.h>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define min(a,b) (a<b?a:b)
#define inf 2000000000
#define ll long long
//#define file
using namespace std;

int a[2001],sum[2001],f[2001][2001],s[2001][2001],n,i,j,k,l,ans,S;

int main()
{
	#ifdef file
	freopen("hdu3506.in","r",stdin);
	#endif
	
	while (scanf("%d",&n)!=EOF)
	{
		fo(i,1,n) scanf("%d",&a[i]),a[i+n]=a[i];
		fo(i,1,n+n) sum[i]=sum[i-1]+a[i];
		
		memset(f,127,sizeof(f));
		fo(i,1,n+n) f[i][i]=0,s[i][i]=i;
		fo(l,2,n)
		{
			fo(i,1,n+n-l+1)
			{
				j=i+l-1;
				fo(k,s[i][j-1],s[i+1][j])
				if (k<j && f[i][k]<inf && f[k+1][j]<inf)
				{
					S=f[i][k]+f[k+1][j]+(sum[j]-sum[i-1]);
					if (S<f[i][j]) f[i][j]=S,s[i][j]=k;
				}
			}
		}
		
		ans=2147483647;
		fo(i,1,n) ans=min(ans,f[i][i+n-1]);
		printf("%d
",ans);
	}
	
	fclose(stdin);
	fclose(stdout);
	return 0;
}