HDU 3516 Tree Construction
区间$dp$,四边形优化。
#pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<vector> #include<map> #include<set> #include<queue> #include<stack> #include<ctime> #include<iostream> using namespace std; typedef long long LL; const double pi=acos(-1.0),eps=1e-10; void File() { freopen("D:\\in.txt","r",stdin); freopen("D:\\out.txt","w",stdout); } template <class T> inline void read(T &x) { char c = getchar(); x = 0; while(!isdigit(c)) c = getchar(); while(isdigit(c)) { x = x * 10 + c - '0'; c = getchar(); } } int n; int x[1100],y[1100],dp[1100][1100],f[1100][1100]; int main() { while(~scanf("%d",&n)) { for(int i=1;i<=n;i++) scanf("%d%d",&x[i],&y[i]); if(n==1) { printf("0\n"); continue; } for(int i=0;i<=n;i++) dp[i][i]=0; for(int i=1;i<n;i++) { dp[i][i+1]=y[i]-y[i+1]+x[i+1]-x[i]; f[i][i+1]=i; } for(int len=3;len<=n;len++) { for(int st=1;st<=n&&st+len-1<=n;st++) { int en=st+len-1; dp[st][en]=0x7FFFFFFF; for(int j=f[st][en-1];j<=f[st+1][en];j++) { if(dp[st][j]+dp[j+1][en]+y[j]-y[en]+x[j+1]-x[st]<dp[st][en]) { dp[st][en]=dp[st][j]+dp[j+1][en]+y[j]-y[en]+x[j+1]-x[st]; f[st][en]=j; } } } } printf("%d\n",dp[1][n]); } return 0; }