hdu1069

本題是一個最長上升子序列的變形,題目給你n種長方體,每種都是無數個,然後讓你堆出最大的高度,如果長方體A能放在長方體B上面,那麼必須滿足長方體A的底面長寬分別都是嚴格小於長方體B的,根據這一點,給定一塊長方體,按照不同的放法,可以生成6個長方體,注意不是3塊。另外比較重要的一點就是,這個問題dp前必須要排序,假設長方體的長寬高設爲x,y,z,因爲前面已經擴展出6個長方體,我就把z當做高,把x,y當做底面,可以考慮下,這樣做法確實包括了所有的情況。那麼問題來了,我如何排序?假如我不排序,我直接按照dp[i]=max(dp[j])+cub[i].z,(j<i,且滿足可以放上去的條件),最後的結果和最長上升子序列一樣,max(dp[i]),這樣的方程去做,結果會對嗎?顯然不對。

個人覺得排序可以這樣去考慮,排序的目的不是保證後面的每塊都能放到它前面任意塊的上面,而是保證,後面的每塊”有可能“放在它前面任意塊的上面,所以有這樣的三級排序,優先級先從x,y,z遞減,這樣能把所有的可能性包含下來,因爲這樣的排序,不存在這樣的情況 ,對於第i個方塊,存在第j個長寬都小於它的方塊,把j放在了i的前面。可以思考一個問題,假如我排序的優先級是,y,x,z或者z,x,y,這樣排序後進行以z爲高的dp,結果還會正確嗎?

附代碼,cub代碼中的用p表示了已經。

#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
struct node
{
    int x,y,z;
}p[201];
int dp[210];
bool cmp(node a,node b)
{
    if(a.x==b.x)
    {
        if(a.y==b.y)
            return a.z>b.z;
        return a.y>b.y;
    }
    return a.x>b.x;
}
int main()
{
    int ca=0;
    int n;
    while(scanf("%d",&n),n)
    {
        int i,j;
        int nn=0;
        for(i=1;i<=n;i++)
        {
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            p[++nn].x=a;p[nn].y=b;p[nn].z=c;
            p[++nn].x=b;p[nn].y=a;p[nn].z=c;
            p[++nn].x=c;p[nn].y=b;p[nn].z=a;
            p[++nn].x=c;p[nn].y=a;p[nn].z=b;
            p[++nn].x=b;p[nn].y=c;p[nn].z=a;
            p[++nn].x=a;p[nn].y=c;p[nn].z=b;

        }
        sort(p+1,p+nn+1,cmp);
        dp[1]=p[1].z;
        int ans=0;
        for(i=2;i<=nn;i++)
        {
            int max=-1;
            int flag=0;
            for(j=i-1;j>=1;j--)
            {
                if(p[j].x>p[i].x&&p[j].y>p[i].y)
                {
                    flag=1;
                    if(max<dp[j])
                        max=dp[j];
                }
            }
            if (flag==0)
                dp[i]=p[i].z;
            else
                dp[i]=max+p[i].z;
            if(ans<dp[i])
                ans=dp[i];
        }
        printf("Case %d: maximum height = %d\n",++ca,ans);
    }
    return 0 ;
}


發佈了58 篇原創文章 · 獲贊 5 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章