HDOJ HDU 1069 Monkey and Banana

HDOJ 1069 Monkey and Banana

题目

点此查看 HDOJ HDU 1069 Monkey and Banana

分类

动态规划

题意

猴子要为了吃到研究人员放在高处的香蕉要尽可能 累 更高的箱子
规则
每种箱子无限
每次累时 上面的箱子的长宽 要严格小于 下面的

题解

首先箱子无限 意味着 每种箱子 都可以 有三种长宽 例如 长宽高 a,b,c、a,c,b、b,c,a
接下来解释DP的方法
i 表示当前箱子号 b[i]表示箱子结构体 b[i].x 表示 i的 长 b[i].y 表示 i的 宽
b[i].h 表示 i的 高
dp[i]表示 以 i 为顶的最大高
dp[i] = max(dp[i],b[i].h + dp[j])(0 <= j < i)(b[i].x < b[j].x && b[i].y < b[j].x)
下面给个dp的表 辅助理解
输入示例

2
6 8 10
5 5 5

箱子种类(长,宽,高)

10 6 8
10 8 6
8 6 10
8 10 6
6 8 10
6 10 8
5 5 5
5 5 5
5 5 5
5 5 5
5 5 5
5 5 5

动态规划表

8
8 6
6 8 16
16 6 8 6
6 16 6 8 16
16 6 16 6 8 8
8 16 6 16 6 8 21
21 8 16 6 16 6 8 21
21 21 8 16 6 16 6 8 21
21 21 21 8 16 6 16 6 8 21
21 21 21 21 8 16 6 16 6 8 21
21 21 21 21 21 8 16 6 16 6 8 21

第一个箱子 高 是 8
第二个箱子 不能把之前的箱子放在上面 高为 6
第三个箱子 首先可以放在第一个上 修改数组为 10 + 8 其次也可以放在 2 上 为 10 + 6 < 18 所以第三个箱子再顶的最大高为 18
依次类推
结果为 Case 1: maximum height = 21

代码

#include <iostream>
#include <cstring>
#include <algorithm>
#define maxn 200

using namespace std ;

struct block
{
    int x;
    int y;
    int h;

};
block b[maxn];
int dp[maxn];

bool cmp(const block & a,const block & b);

int main()
{
    int n,dx,dy,dh,ans,t = 1;
    while(cin >> n && n)
    {
        memset(dp,0,sizeof(dp));
        for(int i = 0;i < n;i++)
        {
            cin >> dx >> dy >> dh;
            b[i*6].x = dx;
            b[i*6].y = dy;
            b[i*6].h = dh;
            b[i*6+1].x = dx;
            b[i*6+1].y = dh;
            b[i*6+1].h = dy;
            b[i*6+2].x = dy;
            b[i*6+2].y = dx;
            b[i*6+2].h = dh;
            b[i*6+3].x = dy;
            b[i*6+3].y = dh;
            b[i*6+3].h = dx;
            b[i*6+4].x = dh;
            b[i*6+4].y = dx;
            b[i*6+4].h = dy;
            b[i*6+5].x = dh;
            b[i*6+5].y = dy;
            b[i*6+5].h = dx;
        }
/*        for(int i = 0;i < n;i++)
        {
            for(int j = 0;j < 6;j++)
            cout << b[i*6+j].x << " " << b[i*6+j].y << " "<< b[i*6+j].h << " " << endl; 
        }
        cout << endl;*/
        sort(b,b+n*6,cmp);
/*        for(int i = 0;i < n;i++)
        {
            for(int j = 0;j < 6;j++)
            cout << b[i*6+j].x << " " << b[i*6+j].y << " "<< b[i*6+j].h << " " << endl; 
        }*/
        for(int i = 0;i < 6*n;i++)
        {
            dp[i] = b[i].h;
            for(int j = i-1;j >=0;j--)
                if(b[j].x > b[i].x && b[j].y > b[i].y)
                    dp[i] = max(dp[i],dp[j]+b[i].h);
        }
        ans = 0;
        for(int i = 0;i < 6 *n;i++)
            ans = max(ans,dp[i]);
        cout << "Case " << t++ << ": maximum height = " << ans << endl; 
    }
    return 0;
}

bool cmp(const block & a,const block & b)
{
    if(a.x > b.x)
        return true;
    else return false;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值