UVA

来源:互联网 发布:ds数据精灵破解 编辑:程序博客网 时间:2024/06/07 22:42

题目链接:点击打开链接

题意:

        有n(n<=30)种立方体,每种都有无穷多个。要求选一些立方体摞成一根尽量高的柱子(可以自行选择哪一条边作为高),使得每个立方体的底面长宽分别严格小于它下方立方体的底面长宽。

思路:

        由于每种立方体有无穷多个,而每个立方体有三种不同的面,那么就可以将问题抽象为最多有多少个长宽严格递减的面,很容易想到每个面最多摞一次。这道题很容易想成贪心,其实这是一道求最长递增子序列的问题。

        首先生成面,需要先对录入的三个数进行排序,然后按照长>宽的规则生成3个面,然后对面进行排序。自定义比较函数时不能用a.length<b.length && a.width<b.width的规则排,因为这样会有一些面无法准确比较,就会产生乱序。需要按照面积进行排序,这样就能保证长宽较大的一定出现在较小的后面。

代码:

#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;int n,dp[100];struct node{    int w,l,h;    bool operator <(node a)const    {        return w<a.w && l<a.l;    }}p[100];bool cmp(node a,node b){    return a.w*a.l<b.w*b.l;}int main(){    int cas=0;    while(scanf("%d",&n) && n)    {        int sq[3],cnt=0;        for(int i=0;i<n;i++)        {            scanf("%d%d%d",&sq[0],&sq[1],&sq[2]);            sort(sq,sq+3);            p[cnt].h=sq[2];            p[cnt].w=sq[0];            p[cnt++].l=sq[1];            p[cnt].h=sq[1];            p[cnt].w=sq[0];            p[cnt++].l=sq[2];            p[cnt].h=sq[0];            p[cnt].w=sq[1];            p[cnt++].l=sq[2];        }        sort(p,p+cnt,cmp);        for(int i=0;i<cnt;i++)        {            dp[i]=p[i].h;            for(int j=0;j<i;j++)            {                if(p[j]<p[i])                    dp[i]=max(dp[i],dp[j]+p[i].h);            }        }        int ans=0;        for(int i=0;i<cnt;i++)            ans=max(ans,dp[i]);        printf("Case %d: maximum height = %d\n",++cas,ans);    }    return 0;}


原创粉丝点击