HDU 3516 四边形优化 解题报告

Tree Construction

Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 1369 Accepted Submission(s): 760

Problem Description

Consider a two-dimensional space with a set of points (xi, yi) that satisfy xi < xj and yi > yj for all i < j. We want to have them all connected by a directed tree whose edges go toward either right (x positive) or upward (y positive). The figure below shows an example tree.
这里写图片描述
Write a program that finds a tree connecting all given points with the shortest total length of edges.

Input

The input begins with a line that contains an integer n (1 <= n <= 1000), the number of points. Then n lines follow. The i-th line contains two integers xi and yi (0 <= xi, yi <= 10000), which give the coordinates of the i-th point.

Output

Print the total length of edges in a line.

Sample Input

5
1 5
2 4
3 3
4 2
5 1
1
10000 0

Sample Output

12
0
【解题报告】
四边形优化
http://download.csdn.net/detail/onepointo/9846259

代码如下:

#include<cstdio>    
#include<cstring>    
#include<algorithm>  
using namespace std;  
#define INF 0x3f3f3f3f

int x[1005],y[1005],s[2005][2005],dp[2005][2005];
int n,i,j,k,l,ans;    

int main()
{  
    while(scanf("%d",&n)!=EOF)
    {  
        memset(dp,INF,sizeof(dp));  
        for(i=1;i<=n;i++)
        {  
            scanf("%d%d",&x[i],&y[i]);  
            dp[i][i]=dp[i+n][i+n]=0;  
            s[i][i]=i,s[i+n][i+n]=i+n;  
        }  
        for(l=2;l<=2*n;l++)
        {                     
            for(i=1;i<=2*n-l+1;++i)
            {             
                j=i+l-1;  
                for(k=s[i][j-1];k<=s[i+1][j];++k)
                {  
                    if(dp[i][j]>dp[i][k]+dp[k+1][j]+(y[k]-y[j])+(x[k+1]-x[i]))
                    {  
                        dp[i][j]=dp[i][k]+dp[k+1][j]+(y[k]-y[j])+(x[k+1]-x[i]);  
                        s[i][j]=k;  
                    }  
                }  
            }  
        }  
        printf("%d\n",dp[1][n]);  
    }  
    return 0;  
}  

让我看到你们的双手

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值