HDU-1069 Monkey and Banana(典型DP)

題目描述

一組研究人員正在設計一項實驗,以測試猴子的智商。他們將掛香蕉在建築物的屋頂,同時,提供一些磚塊給這些猴子。如果猴子足夠聰明,它應當能夠通過合理的放置一些磚塊建立一個塔,並爬上去喫他們最喜歡的香蕉。

研究人員有n種類型的磚塊,每種類型的磚塊都有無限個。第i塊磚塊的長寬高分別用xi,yi,zi來表示。 同時,由於磚塊是可以旋轉的,每個磚塊的3條邊可以組成6種不同的長寬高。

在構建塔時,當且僅當A磚塊的長和寬都分別小於B磚塊的長和寬時,A磚塊才能放到B磚塊的上面,因爲必須留有一些空間讓猴子來踩。

你的任務是編寫一個程序,計算猴子們最高可以堆出的磚塊們的高度。

輸入格式

輸入文件包含多組測試數據。
每個測試用例的第一行包含一個整數n,代表不同種類的磚塊數目。n<=30.
接下來n行,每行3個數,分別表示磚塊的長寬高。
當n= 0的時候,無需輸出任何答案,測試結束。

輸出格式

對於每組測試數據,輸出最大高度。格式:Case 第幾組數據: maximum height = 最大高度

樣例輸入

1
10 20 30 
2 
6 8 10 
5 5 5 
7 
1 1 1 
2 2 2 
3 3 3 
4 4 4 
5 5 5 
6 6 6 
7 7 7 
5 
31 41 59 
26 53 58 
97 93 23 
84 62 64 
33 83 27 
0

樣例輸出

Case 1: maximum height = 40
Case 2: maximum height = 21 
Case 3: maximum height = 28 
Case 4: maximum height = 342 






題解:

  • 對於每一塊磚,有三條邊可以作爲高,則另外兩條邊可分別做長、寬,故共有6種擺法
  • 將6*n種磚加入到數組中,再將其按長度遞增排序(長度相等則寬度遞增)
  • 定義狀態dp[i]將第i個箱子作爲最底部時的最高高度,因已保證長度遞增,所以只需要判斷寬度和長度是否嚴格遞增。如此一來,問題便變得像最長遞增子串了。
  • 狀態轉移: dp[i]=max(dp[k]+a[i].height)k<ia[i].length>a[k].length,  a[i].width>a[k].widthdp[i] = \max (dp[k]+a[i].height) 其中k<i且a[i].length > a[k].length,\ \ a[i].width > a[k].width
#include <bits/stdc++.h>
using namespace std;

const int maxn = 35 * 6;

struct box{
    int l,w,s,h;
};

bool cmp(box &a, box &b)
{
    if(a.l==b.l) return a.w < b.w;
    return a.l < b.l;
}

box bo[maxn];
int dp[maxn];

int solve(int sn)
{
    int ans = 0;
    for(int i=0;i<sn;i++)
    {
        dp[i] = bo[i].h;
        for(int j=0;j<i;j++)
            if(bo[j].l<bo[i].l && bo[j].w < bo[i].w && dp[j]+bo[i].h > dp[i])
                dp[i] = dp[j]+bo[i].h;
        ans = max(ans, dp[i]);
    }
    return ans;
}

int main()
{
    int n,kase = 0;
    cin >> n;
    while(n)
    {
        int a,b,c;
        for(int i=0;i<n;i++)
        {
            scanf("%d %d %d",&a,&b,&c);
            // 六種擺法
            bo[i*6+5].h = bo[i*6+4].w = bo[i*6+3].l = bo[i*6+2].h = bo[i*6+1].w = bo[i*6].l = a;
            bo[i*6+5].l = bo[i*6+4].h = bo[i*6+3].w = bo[i*6+2].w = bo[i*6+1].l = bo[i*6].h = b;
            bo[i*6+5].w = bo[i*6+4].l = bo[i*6+3].h = bo[i*6+2].l = bo[i*6+1].h = bo[i*6].w = c;
        }
        int sn = 6*n;
        sort(bo, bo+sn, cmp);
        cout <<"Case " << ++kase << ": maximum height = " << solve(sn) << endl;
        scanf("%d",&n);
    }


    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章