码迷,mamicode.com
首页 > 其他好文 > 详细

【四边形】 HDU 3516 Tree Construction

时间:2015-08-02 16:28:16      阅读:118      评论:0      收藏:0      [点我收藏+]

标签:

通道

题意:二维坐标上的点,建一个长度和最小的树包含全部点

思路:

定义状态 dp[i,j]表示点i到点j合并在一起的最小花费(树枝的长度),
状态转移方程:dp[i,j]= min(dp[i,k]+dp[k+1,j]+cost(i,j) ) i<k<j
cost(i,j)=py[k]-py[j]+px[k+1]-px[i];
当j固定时,cost(i,j)单调递减函数
我们猜测cost(i,j)满足四边形不等式
证明: F(i)=cost(i,j+1)-cost(i,j)=py[j]-py[j+1]是一个与i无关的多项式,
所以j固定时,F(i)满足四边形不等式,得证。
s[i,j]=k;s[i-1,j] <= s[i,j] <= s[i,j+1];
由于决策s具有单调性,因此状态转移方程可修改为:

技术分享


代码:

技术分享
#include <iostream>  
#include <cstdio>   
#include <cstring>
#include <algorithm>
using namespace std;  
int dp[1010][1010];
int s[1010][1010];    
int main(){
    int n;
    int x[1010];
    int y[1010];
    while(scanf("%d",&n)!=EOF){
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=n;i++){
            scanf("%d%d",&x[i],&y[i]);
            s[i][i]=i;
        }
        for(int ln=2;ln<=n;ln++){
            for(int i=1;i<=n-ln+1;i++){
                dp[i][i+ln-1]=999999;
                for(int j=s[i][i+ln-2];j<=s[i+1][i+ln-1];j++){
                    if(dp[i][i+ln-1]>dp[i][j]+dp[j+1][i+ln-1]+abs(x[j+1]-x[i])+abs(y[i+ln-1]-y[j])){
                        dp[i][i+ln-1]=dp[i][j]+dp[j+1][i+ln-1]+abs(x[j+1]-x[i])+abs(y[i+ln-1]-y[j]);
                        s[i][i+ln-1]=j;
                    }
                }
            }
        }
        printf("%d\n",dp[1][n]);  
    }
    return 0;  
}
View Code

 

【四边形】 HDU 3516 Tree Construction

标签:

原文地址:http://www.cnblogs.com/Rojo/p/4695877.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!