HDU 1069 Monkey and Banana 基础DP

ps:对于菜鸡来说,基础不代表简单 &_&

给N个 长宽高为xi,yi,zi的木块,问最高能叠多高;要求相邻的两个木块:上面木块的长和宽都必须严格小于它下面的;

分析:

首先像的还是枚举,只要枚举出所有情况的ans,保留最大的那个就是答案了;问题就在于怎么枚举。再深入分析一下,对于第i层木块来说,如果这个木块是最优解,那么它下面的第i-1层的这个木块肯定也要是最优解。所以如果说dp[x][y]是第i层应该放的那个木块,那么 dp[x][y] +=max{dp[x'][y'] | x'>x,y'>y};这样几乎就转化成数塔问题了,只要从底往上算上去,dp[最小的那个木块]就是答案;问题在于我们无法对dp[x][y]按照想要的顺序排序;

所以要像个办法转变,设一个结构体:

struct node
{
    int x,y; // 长宽
    int h,sum; //高和当前高度总值

}dp[maxn];
分析可以发现一个性质:x'>x  &&  y'>y  所以 x’+y' > x+y 就可以对dp数组桉树 x+y 排序了。

然后就可以利用前面的dp[x][y] +=max{dp[x'][y'] | x'>x,y'>y};

值得说的是,在最优解中,长宽相对最小的那个不一定非要放上去;所以答案不是dp[最小].sum,没考虑到这个因此wa了n次

<span style="font-size:10px;">/* ***********************************************
Author        :angon
************************************************ */
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <stack>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
#define REP(i,k,n) for(int i=k;i<n;i++)
#define REPP(i,k,n) for(int i=k;i<=n;i++)
#define scan(d) scanf("%d",&d)
#define scann(n,m) scanf("%d%d",&n,&m)
#define LL long long
#define maxn 1005
#define mod 100000007

struct node
{
    int x,y;
    int h,sum;

}dp[maxn];
bool cmp(node n1,node n2)
{
    if(n1.x+n1.y!=n2.x+n2.y)  //注意这个排序方式
        return n1.x+n1.y>n2.x+n2.y;
    return n1.x>n2.x || (n1.x==n2.x && n1.y>n2.y);
}
int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    int n,x,y,z,ca=1;
    while(scanf("%d",&n) && n)
    {
        memset(dp,0,sizeof(dp));
        int k=0;
        for(int i=0;i<n;i++)
        {
            scanf("%d%d%d",&x,&y,&z);
            dp[k].x=x; dp[k].y=y; dp[k].h=z; dp[k].sum=z; k++;
            dp[k].x=y; dp[k].y=z; dp[k].h=x; dp[k].sum=x; k++;
            dp[k].x=x; dp[k].y=z; dp[k].h=y; dp[k].sum=y; k++;
        }
        sort(dp,dp+k,cmp);
        for(int i=1;i<k;i++)
        {
            int temp=0;
            for(int j=0;j<i;j++)
            {
                if(dp[j].x > dp[i].x && dp[j].y > dp[i].y || dp[j].x > dp[i].y && dp[j].y > dp[i].x )
                 {
                     temp=max(temp,dp[j].sum);
                 }
            }
            dp[i].sum += temp;
        }
        int Max=0;
        REP(i,0,k) //一开始没考虑到这个wa了n次
            Max=max(dp[i].sum,Max);
        printf("Case %d: maximum height = %d\n",ca++,Max);
    }
    return 0;
}</span>

你可能感兴趣的:(HDU 1069 Monkey and Banana 基础DP)