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 }

猜你喜欢

转载自www.cnblogs.com/Ressed/p/9457561.html