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);
    }


}

猜你喜欢

转载自blog.csdn.net/qq_37591656/article/details/81540948