UVA 437 The Tower of Babylon

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=378

此题给出不同种类的矩形块(即给出x,y,z,代表其长宽高的元素),找出其长,宽均依次递减,并且最高的塔;

即是求最长下降子序列,只是权值为高。矩形块可以用无限多次。x,y,z,任意一个都可以作高,而其它两项为长宽。由于没有顺序要求,因此要将长,宽降序排列,这样就可以只比较前面的,而不需要顾及其它。

#include
   
   
    
    
#include
    
    
     
     
#include
     
     
      
      
using namespace std;
int dp[100];
int dir[3][3]={{0,1,2},{0,2,1},{1,2,0}};
int tow[100][3];
struct node
{
    int l,w,h;
};
node to[100];
bool cmb(node a,node b)
{
    if(a.l == b.l)
    {
        if(a.w == b.w)
            return a.h > b.h;
        return a.w > b.w;
    }
    return a.l > b.l;
}
bool ok(int x,int y)
{
    if(to[x].l < to[y].l && to[x].w < to[y].w)
        return true;
    return false;
}
int main()
{
    int n,i = 1;
    while(scanf("%d",&n) == 1 && n)
    {
        int j,k;
        n*=3;
        for(j = 1; j <= n ;j+=3)
        {
            scanf("%d%d%d",&tow[j][0],&tow[j][1],&tow[j][2]);
            for(k = 0; k < 3; k++)
            {
                to[j+k].l = tow[j][dir[k][0]];
                to[j+k].w = tow[j][dir[k][1]];
                to[j+k].h = tow[j][dir[k][2]];
                if(to[j+k].l < to[j+k].w)
                {
                    int t = to[j+k].l;
                    to[j+k].l = to[j+k].w;
                    to[j+k].w = t;
                }
            }
        }
        sort(to+1,to+n+1,cmb);/*排序*/
        memset(dp,0,sizeof(dp));
        int ans = 0;
        //用“//”的是另一种方式,不过原理是一样的
        for(j = 1 ;j <= n; j++)
        {
            dp[j] = to[j].h;
            //int m = 0;
            for(k = 1; k < j; k++){
                if(ok(j,k))
                { 
                    /*如果前面符合条件的有权值与当前权值的和比当前的高度高,则更新为当前的高度*/
                    if(dp[j] < dp[k] + to[j].h)//if(dp[k] > m)  //找到前面符合条件的最高的高度
                    {
                         //m = dp[k];  
                        dp[j] = dp[k] + to[j].h;
                    }
                }
            }
            //dp[j] = m + to[j].h; //当前高度更新
            if(dp[j] > ans)/*找最高的高度*/
                ans = dp[j];
        }
        printf("Case %d: maximum height = %d\n",i,ans);
        i++;
    }
}

     
     
    
    
   
   


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值