zoukankan      html  css  js  c++  java
  • [恢]hdu 1069

    2011-12-22 17:22:12

    地址:http://acm.hdu.edu.cn/showproblem.php?pid=1069

    题意:有n种立方体,长宽高分别是x[i], y[i], z[i],每种数量无限。可以随意旋转。把他们垒起来,要求上面的立方体底面长和宽一定要分别小于下面立方体顶面的长和宽。问最高能垒多高。

    mark:一开始没看到数量无限,以为是单个的。想了好久不会做,后来看别人的解释才知道。

    每个方块扩展成3个,分别穷举出3边各为高的情况,排序,然后dp。本质是LIS。还蛮简单的。

    但是wa了n次,快折腾死我了。排序的策略我选择的是先x和x比,然后y和y比。但是我忽略了有x1<y2 && x2<y1的情况。。。

    可以换成按面积排序,也可以换成按min(x,y)排序。总之要保证小的在前大的在后。

    代码:

    # include <stdio.h>
    # include <stdlib.h>


    typedef struct node{
    int x, y, z ;
    }node ;


    int n ;
    node pt[1010*3] ;
    int dp[1010*3] ;


    int max(int a, int b){return a>b?a:b;}


    int cmp(const void *a, const void *b)
    {
    node *p = (node*)a, *q = (node*)b ;
    // if (p->x != q->x) return p->x - q->x ;
    // return p->y - q->y ;
    return p->x*p->y - q->x * q->y ;
    }


    int gao()
    {
    int i, j, ans ;
    qsort(pt, 3*n, sizeof(node), cmp) ;
    ans = pt[0].z ;
    for (i = 0 ; i < 3*n ; i++)
    {
    dp[i] = pt[i].z ;
    for (j = 0 ; j < i ; j++)
    {
    if ((pt[j].x < pt[i].x && pt[j].y < pt[i].y) ||
    (pt[j].y < pt[i].x && pt[j].x < pt[i].y))
    dp[i] = max(dp[i], dp[j]+pt[i].z) ;
    }
    ans = max(ans, dp[i]) ;
    }
    return ans ;
    }


    int main ()
    {
    int a, b, c, i, nCase = 1 ;
    while (~scanf ("%d", &n) && n)
    {
    for (i = 0 ; i < n ; i++)
    {
    scanf ("%d%d%d", &a, &b, &c) ;
    pt[3*i].x = a, pt[3*i].y = b, pt[3*i].z = c ;
    pt[3*i+1].x = b, pt[3*i+1].y = c, pt[3*i+1].z = a ;
    pt[3*i+2].x = c, pt[3*i+2].y = a, pt[3*i+2].z = b ;
    }
    printf ("Case %d: maximum height = %d\n",nCase++, gao()) ;
    }
    return 0 ;
    }



  • 相关阅读:
    新购服务器流程
    nginx代理证书使用方法
    一键部署lnmp脚本
    mysql主从库配置读写分离以及备份
    Linux入门教程(更新完毕)
    Git 工作流程
    Git远程操作
    常用Git命令
    js数组去重
    Sublime Text设置快捷键让html文件在浏览器打开
  • 原文地址:https://www.cnblogs.com/lzsz1212/p/2315321.html
Copyright © 2011-2022 走看看