poj 2241 The Tower of Babylon(DP…

题意:有N种不同尺过的block(矩形) 每一种数量无限,可以任意旋转 也就是说 x y z 其中可任意两个为底,另一个为高。问你 最多能堆多高,要求上面的block要严格的小于下面block的底 即xj < xi && yj < yi

思路:动态规划 虽说每种block数量无限,但其实最多只能用三块。对全部的block 排序 x 降序 x相同 y 降序。 这样就能转换成最大非增递子序列。

//172K      0MS
#include <stdio.h>
#include <algorithm>
#define M 100
using namespace std;

struct data
{
      int x,y,h;
}node[M];
int num[3];
void _sort()          //让num从大到小排
{
      for (int j = 1;j < 3;j ++)
              for (int i = 0;i < 3-j;i ++)
                      if (num[i] < num[i+1])
                      {
                              int tem = num[i];
                              num[i] = num[i+1];
                              num[i+1] = tem;
                      }
}
bool cmp (data a,data b)
{
      if (a.x > b.x)
              return true;
      if (a.x == b.x&&a.y > b.y)
              return true;
      return false;
}
int main ()
{
      int n,i,k,max,count = 0,tall[M];
      while (scanf ("%d",&n)&&n)
      {
              k = 0;
              for (i = 0;i < n;i ++)
              {
                      scanf ("%d%d%d",&num[0],&num[1],&num[2]);
                      _sort ();
                      node[k].x = num[0],node[k].y = num[1],node[k++].h = num[2];
                      node[k].x = num[0],node[k].y = num[2],node[k++].h = num[1];
                      node[k].x = num[1],node[k].y = num[2],node[k++].h = num[0];
              }
              sort (node,node + k,cmp);
              for (i = 0;i < k;i ++)      //dp求最大非递增子序列
              {
                      max = 0;
                      for (int j = 0;j < i;j ++)
                              if ((node[i].x < node[j].x&&node[i].y < node[j].y)&&tall[j] >= max)
                                      max = tall[j];
                      tall[i] = max + node[i].h;
              }

              max = tall[0];
              for (i = 1;i < k;i ++)
                      max = max > tall[i]?max : tall[i];
              printf ("Case %d: maximum height = %d\n",++count,max);
      }
      return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值