UVA 437 "The Tower of Babylon" (DAG上的动态规划)

传送门

 

题意

  有 n 种立方体,每种都有无穷多个。

  要求选一些立方体摞成一根尽量高的柱子(在摞的时候可以自行选择哪一条边作为高);

  立方体 a 可以放在立方体 b 上方的前提条件是立方体 a 的底面长宽分别严格小于立方体 b 的底面长宽;

  求最大高度;

思路

  对于立方体 a(x,y,z)((长,宽,高)),因为每个立方体都有无穷个,所以 a 要拆成三个;

  a1(x,y,z) , a2(x,z,y) , a3(y,z,x) 即分别以 z,y,x 作为高;

  对于任意两个立方体 a,b ,如果 b 可以放在 a 的上方,那么连一条边 a->b,意思是 a 的上方可以放 b;

  预处理出所有的点,以此构图,然后求出高最大的那条路经的高,输出即可;

AC代码

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 #define mem(a,b) memset(a,b,sizeof(a))
 5 const int maxn=100;
 6 
 7 int n;
 8 int num;
 9 int head[maxn];
10 struct Edge
11 {
12     int to;
13     int next;
14 }G[maxn*maxn];
15 void addEdge(int u,int v)
16 {
17     G[num]={v,head[u]};
18     head[u]=num++;
19 }
20 struct Date
21 {
22     int x,y;
23 }_date[maxn];
24 ll h[maxn];
25 ll dp[maxn];///dp[i]:以立方体i为最底层的立方体可以形成的最大高度
26 
27 ll F(int u)
28 {
29     ll &ans=dp[u];
30     if(ans != -1)
31         return ans;
32     ans=h[u];
33     for(int i=head[u];~i;i=G[i].next)
34     {
35         int v=G[i].to;
36         ans=max(ans,F(v)+h[u]);
37     }
38     return ans;
39 }
40 bool isSat(int i,int j)
41 {
42     return _date[i].x > _date[j].x && _date[i].y > _date[j].y ||
43            _date[i].x > _date[j].y && _date[i].y > _date[j].x ? true:false;
44 }
45 ll Solve()
46 {
47     ///最多可能加入(3*n)^2条边
48     ///G数组不要开小了
49     for(int i=1;i <= 3*n;++i)
50         for(int j=1;j <= 3*n;++j)
51             if(isSat(i,j))///判断立方体j是否可以放在立方体i上
52                 addEdge(i,j);
53     mem(dp,-1);
54     for(int i=1;i <= 3*n;++i)///以i作为底层的立方体
55         dp[i]=F(i);
56 
57     return *max_element(dp+1,dp+3*n+1);
58 }
59 void Init()
60 {
61     num=0;
62     mem(head,-1);
63 }
64 int main()
65 {
66     int kase=0;
67     while(~scanf("%d",&n) && n)
68     {
69         Init();
70         for(int i=1;i <= n;++i)
71         {
72             int x,y,z;
73             scanf("%d%d%d",&x,&y,&z);
74 
75             ///第i个立方体变为三个编号为i*3,i*3-1,i*3-2的立方体
76             int cnt=i*3;
77             _date[cnt]={x,y};
78             h[cnt--]=z;
79 
80             _date[cnt]={x,z};
81             h[cnt--]=y;
82 
83             _date[cnt]={y,z};
84             h[cnt--]=x;
85         }
86         printf("Case %d: maximum height = %lld\n",++kase,Solve());
87     }
88     return 0;
89 }
View Code

 

posted @ 2019-05-29 20:31  HHHyacinth  阅读(133)  评论(0编辑  收藏  举报