1. 程式人生 > >HDU Monkey and Banana

HDU Monkey and Banana

題意:

給你n種木塊,木塊的個數不限,規範木塊堆積的規則,底下的木塊的長、寬必須都大於上面木塊的長寬。現在問你最高能疊的高度

解法:

這個題沒想通是因為,每種木塊分成 底、高來看的話,有三種狀態( 為什麼底可以不用細分?因為底的兩邊可以互換,相當於一個長方體,轉了一下 ,因此底看成整體),那我們需要在一個單位上儲存三種狀態。那麼在找子結構的時候,就需要判斷子結構的某狀態是可用的,需要很多標記,況且自身也是可以堆起來的。

正解:

多重揹包思維:每種狀態轉換成多種狀態,那麼就拆分開來 。 例如本題,輸入一種木塊的引數,我們構造出三塊固定 底 高 的木塊,這樣就好做了。

程式碼:

/*
被教育了 , 一種木塊 可以轉換成多種狀態, 而且取木塊的次數不限的時候, 可以把各個狀態當成一個新的木塊,
多重揹包思維。小本本記下了

*/
#include <iostream>
#include <bits/stdc++.h>

using namespace std;
const int maxn = 35 ;
int dp[maxn*3];

struct Node
{
    int l,r,h,area;

}node[maxn*3];

bool cmp(Node a, Node b)
{
    return a.area > b.area;
}
int
main() { int n; int cas = 1; while(scanf("%d",&n) && n) { for(int i=1;i<=3*n;i++) { int a,b,c; scanf("%d%d%d",&a,&b,&c); node[i].l = a, node[i].r = b, node[i].h = c; node[i].area = a*b; i++; node[i].l = a, node[i].r = c, node[i].h = b; node[i].area = a*c
; i++; node[i].l = b, node[i].r = c, node[i].h = a; node[i].area = b*c; } sort(node+1,node+1+3*n,cmp); int ans = 0; for(int i=1;i<=3*n;i++) { int tmp = 0; for(int j=1;j<i;j++) // { if( (node[i].r<node[j].r && node[i].l < node[j].l) || (node[i].r< node[j].l && node[i].l < node[j].r) ) if(dp[j] > tmp) tmp = dp[j]; } dp[i] = tmp + node[i].h; ans = max(ans,dp[i]); } printf("Case %d: maximum height = %d\n",cas++,ans); } }