hdu3516 Tree Construction (区间dp+四边形优化)
构造方法肯定是把相邻两个点连到一起,变成一个新点,然后再把新点和别的点连到一起....
设f[i,j]为把第i到j个点都连到一起的代价,那么答案就是f[1,n]
f[i,j]=min{f[i,k]+f[k+1,j]+x[k+1]-x[i]+y[k]-y[j]} (画一画就知道了)
然后显然满足四边形不等式(怎么就显然了??)
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<vector> 5 #include<queue> 6 #include<cmath> 7 #define inf 0x3f3f3f3f 8 #define LL long long int 9 using namespace std; 10 const int maxn=1010; 11 12 LL rd(){ 13 LL x=0;char c=getchar();int neg=1; 14 while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();} 15 while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); 16 return x*neg; 17 } 18 19 int N,f[maxn][maxn][2],p[maxn][2]; 20 21 int main(){ 22 int i,j,k; 23 while(~scanf("%d",&N)){ 24 for(i=1;i<=N;i++) p[i][0]=rd(),p[i][1]=rd(),f[i][i][1]=i; 25 if(N==1){printf("0\n");continue;} 26 for(int t=1;t<N;t++){ 27 for(i=1;i<=N;i++){ 28 j=i+t;f[i][j][0]=inf; 29 for(k=f[i][j-1][1];k<=j-1&&k<=f[i+1][j][1];k++){ 30 int a=f[i][k][0]+f[k+1][j][0]+p[k][1]-p[j][1]+p[k+1][0]-p[i][0]; 31 if(a<f[i][j][0]) f[i][j][0]=a,f[i][j][1]=k; 32 } 33 } 34 } 35 printf("%d\n",f[1][N][0]); 36 } 37 return 0; 38 }