原题: http://acm.hdu.edu.cn/showproblem.php?pid=3516
题意:
给出n个左上角到右下角的点,用向右和向上的边连起来,问边长和的最小值。
解析:
一开始以为点是随机分布的,状态方程都想不出来。
用
表示连接
到
的最短变长,显然
讨论面那串是否符合四边形不等式:
相当于
中的截距的相反数,所以下标越大值越大,故不等式成立。
#include<bits/stdc++.h>
using namespace std;
#define LL long long
int dp[1009][1009];
int best[1009][1009];
int x[1009],y[1009];
int n;
int main(){
while(cin>>n){
memset(dp,0x3f,sizeof dp);
for(int i=1;i<=n;i++)
scanf("%d%d",x+i,y+i),dp[i][i]=0,best[i][i]=i;
for(int len=2;len<=n;len++){
for(int i=1;i+len-1<=n;i++){
int j=i+len-1;
for(int k=best[i][j-1];k<=best[i+1][j];k++){
if(dp[i][k]+dp[k+1][j]+(x[k+1]-x[i])+(y[k]-y[j])<dp[i][j]){
dp[i][j]=dp[i][k]+dp[k+1][j]+(x[k+1]-x[i])+(y[k]-y[j]);
best[i][j]=k;
}
}
}
}
printf("%d\n",dp[1][n]);
}
}