zoukankan      html  css  js  c++  java
  • 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
    ",++kase,Solve());
    87     }
    88     return 0;
    89 }
    View Code
  • 相关阅读:
    linux使用rm-rf删除之文件恢复
    性能测试常见瓶颈分析及调优方法
    性能压测QPS 和 TPS区别
    Linux查看系统性能
    Python中split()和split(" ")的区别
    Python-标准库之functools
    Python-内置函数_@propery、@classmethod、@staticmethod详解
    Python-类的内置方法中__repr__和__str__的区别
    Python-标准库之运算符替代函数Operator
    Python-标准库之迭代器-itertools
  • 原文地址:https://www.cnblogs.com/violet-acmer/p/10946003.html
Copyright © 2011-2022 走看看