HDU Monkey and Banana
阿新 • • 發佈:2019-02-17
題意:
給你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);
}
}