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

【四边形不等式】HDU3516-Tree Construction

时间:2016-09-25 18:53:18      阅读:121      评论:0      收藏:0      [点我收藏+]

标签:

【题目大意】

给定n个点(x,y),并且保证xi<xj&&yi>yj当i<j。要求建一颗树,树的边只能向上和向右生长,求将所有点都连起来树的长度最小。

技术分享

【思路】

定义状态 dp[i,j]表示点i到点j合并在一起的最小花费(树枝的长度)。如dp[3,4]表示图中绿色的这一段。

技术分享


状态转移方程:dp[i,j]= min(dp[i,k]+dp[k+1,j]+w(i,j) ) i<k<j,w(i,j)=py[k]-py[j]+px[k+1]-px[i]。

【注意点】

初始化的时候s[i][i]=i-1,因为i<k<j,k不能取i。

 

 1 #include<cstdio>  
 2 #include<cstring>  
 3 #include<iostream>  
 4 #include<algorithm>  
 5 using namespace std;  
 6 const int MAXN=1010;
 7 const int INF=1e9;
 8 //这里INF设太大会溢出来 
 9 int T,t,n;  
10 int dp[MAXN][MAXN],s[MAXN][MAXN];
11 int x[MAXN],y[MAXN];  
12 
13 void solve()
14 {
15     for(int i=n;i>=1;i--)  
16         for(int j=i+1;j<=n;j++)  
17         {  
18             dp[i][j]=INF;  
19             for(int k=s[i][j-1];k<=s[i+1][j];k++)  
20             {  
21                   int ret=dp[i][k]+dp[k+1][j]+x[k+1]-x[i]+y[k]-y[j];  
22                    if(ret<dp[i][j])  
23                    {  
24                     dp[i][j]=ret;  
25                     s[i][j]=k;  
26                 }  
27             }  
28         }  
29     printf("%d\n",dp[1][n]);  
30 }
31 
32 void init()
33 {
34     for(int i=1;i<=n;i++)  
35         scanf("%d%d",&x[i],&y[i]); 
36     memset(dp,0,sizeof(dp));
37     memset(s,0,sizeof(s)); 
38     for(int i=1;i<=n;i++)  
39         s[i][i]=i-1;  
40 }
41 
42 int main()  
43 {   
44     while(~scanf("%d",&n))  
45     {  
46         init();
47         solve();
48     }  
49 }  

 

【四边形不等式】HDU3516-Tree Construction

标签:

原文地址:http://www.cnblogs.com/iiyiyi/p/5906424.html

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