HDU 3516 Tree Construction
_(:3」∠)_
四边形优化
dp[i][j]:第i个点和第j个点合并的最小花费
cost(i,j,k):第i和第j个点通过第k个点合并所需要的花费
容易写出:dp[i][j]=min{dp[i][k]+dp[k+1][j]+cost(i,j,k)}
易证cost函数为凸
然后四边形优化之
#include<cstdio> #include<cstring> #include<algorithm> #include<vector> #include<iostream> #include<queue> #include<stack> #include<cmath> #include<map> #define BUG printf("hehe\n") #define INF 0x3f3f3f3f #define ll long long using namespace std; struct Point { int x,y; }point[1010]; int dp[1010][1010]; int s[1010][1010]; int cost(int i,int j,int k) { return point[k].y-point[j].y+point[k+1].x-point[i].x; } int main() { int n; while(scanf("%d",&n)==1) { for(int i=1;i<=n;++i) scanf("%d%d",&point[i].x,&point[i].y); for(int i=1;i<=n;++i) s[i][i]=i; for(int len=1;len<n;++len) { for(int i=1;i<=n-len;++i) { int j=i+len; dp[i][j]=INF; for(int k=s[i][j-1];k<=s[i+1][j]&&k<j;++k) { //这里k<j很关键= =、不然连样例都出不了 if(dp[i][j]>dp[i][k]+dp[k+1][j]+cost(i,j,k)) { s[i][j]=k; dp[i][j]=dp[i][k]+dp[k+1][j]+cost(i,j,k); } } } } printf("%d\n",dp[1][n]); } }