HDU 1069 Monkey and Banana

这篇博客介绍了一个关于猴子智商测试的实验,猴子需要通过堆叠砖块来获取悬挂的香蕉。每种砖块有6种排列方式,需要按特定条件排序并计算最长递增子序列(LIS)以确定猴子能堆出的最大高度。代码实现中,首先对所有砖块的排列进行排序,然后应用线性DP方法计算LIS,从而得出最大高度。
摘要由CSDN通过智能技术生成

题意

一组研究人员正在设计一项实验,以测试猴子的智商。
他们将挂香蕉在建筑物的屋顶,同时,提供一些砖块给这些猴子。
如果猴子足够聪明,它应当能够通过合理的放置一些砖块建立一个塔,并爬上去吃他们最喜欢的香蕉。
研究人员有n种类型的砖块,每种类型的砖块都有无限个。
第i块砖块的长宽高分别用xi,yi,zi来表示。
同时,由于砖块是可以旋转的.
在构建塔时,当且仅当A砖块的长和宽都分别小于B砖块的长和宽时,
A砖块才能放到B砖块的上面,因为必须留有一些空间让猴子来踩。
 
你的任务是编写一个程序,计算猴子们最高可以堆出的砖块们的高度。

题解

[线性DP--LIS模型]

分析:
    通过题意,可以分析得出,每一种类型的砖可以分成 6 种不同类型的
    在将其按照长宽小的放前面, 求LIS
    (为什么要排序,因为LIS与序顺序有关)
    (所以要构造一个序列使得 LIS尽可能长)

Code

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
#define read(a) scanf("%d", &a)
#define readl(a) scanf("%lld", &a)
#define readf(a) scanf("%lf", &a)
#define readc(a) scanf("%c", &a)
#define reads(a) scanf("%s", a)
#define Buff ios::sync_with_stdio(false)
#define mem(a) memset(a, 0, sizeof a)
#define pb push_back
const int INF = 1e9 + 7;
const int N = 1e5 + 7;
const int M = 1e6 + 7;
const ll mod = 1e9 + 7;
struct node
{
    int x, y, z;
    node(int x = 0, int y = 0, int z = 0):x(x), y(y), z(z){}
    bool operator<(const node& A)const
    {
        return (x < A.x || (x == A.x && y < A.y));
    }
}block[N];
int dp[N];

int main()
{
    Buff;
    int n, Case = 0;
    while(cin >> n, n)
    {
        n *= 6;
        for(int i = 1,xi,yi,zi; i <= n;)
        {
            cin >> xi >> yi >> zi;
            block[i++] = node(xi, yi, zi);
            block[i++] = node(xi, zi, yi);
            block[i++] = node(yi, xi, zi);
            block[i++] = node(yi, zi, xi);
            block[i++] = node(zi, xi, yi);
            block[i++] = node(zi, yi, xi);
        }
        sort(block+1, block+n+1);
        int ans = 0;
        for(int i = 1; i <= n; i++)
        {
            dp[i] = block[i].z;
            for(int j = 1; j < i; j++)
                if(block[j].x < block[i].x && block[j].y<block[i].y && dp[i] < dp[j] + block[i].z)
                    dp[i] = dp[j] + block[i].z;
            ans = max(ans, dp[i]);
        }
        cout << "Case " << ++Case << ": maximum height = " << ans << "\n";
    }

    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值