「暑期训练」「基础DP」 Monkey and Banana (HDU-1069)

题意与分析

给定立方体(个数不限),求最多能堆叠(堆叠要求上方的方块严格小于下方方块)的高度。
表面上个数不限,问题是堆叠的要求决定了每个方块最多可以使用三次。然后就是对 3n 3 n 的方格序列用LIS。
注意:排序和求LIS的标准不同,否则答案会错误。

代码

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#define MP make_pair
#define PB push_back
#define fi first
#define se second
#define ZERO(x) memset((x), 0, sizeof(x))
#define ALL(x) (x).begin(),(x).end()
#define rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define per(i, a, b) for (int i = (a); i >= (b); --i)
#define QUICKIO                  \
    ios::sync_with_stdio(false); \
    cin.tie(0);                  \
    cout.tie(0);
using namespace std;

template<typename T>
T read()
{
    T tmp; cin>>tmp;
    return tmp;
}

struct Block
{
    int x,y,z; 
    Block() {}
    Block(int _x,int _y,int _z):x(_x),y(_y),z(_z) {}
    bool operator < (const Block& rhs) const
    {
        if(x==rhs.x) return y>rhs.y;
        else return x>rhs.x;
    }
};

vector<Block> vec;
void add_vec(int x,int y,int z)
{
    if(x>y) swap(x,y);
    if(x>z) swap(x,z);
    if(y>z) swap(y,z);
    vec.PB(Block(y,z,x));
    vec.PB(Block(x,z,y));
    vec.PB(Block(x,y,z));
}
int main()
{
    int n,kase=0; 
    while(cin>>n)
    {
        vec.clear();
        if(!n) break;
        rep(i,1,n)
        {
            int x,y,z; cin>>x>>y>>z;
            add_vec(x,y,z);
        }
        sort(ALL(vec));
        int dp[105],sz=vec.size(); ZERO(dp);
        //rep(i,0,sz-1) cout<<dp[i]<<" ";
        //cout<<endl;
        rep(i,0,sz-1)
        {
            dp[i]=vec[i].z;
            rep(j,0,i-1)
            {
                //cout<<vec[j].x<<" "<<vec[i].x<<" "<<vec[j].y<<" "<<vec[i].y<<endl;
                if(vec[j].x>vec[i].x && vec[j].y>vec[i].y)
                {
                    dp[i]=max(dp[i],dp[j]+vec[i].z);
                    //cout<<"Yeah, "<<j<<">"<<i<<endl;
                }
            }/*
            rep(j,0,sz-1)
                cout<<dp[j]<<" ";
            cout<<endl;
        */}
        int maxans=-1;
        rep(i,0,sz-1)
            maxans=max(maxans,dp[i]);
        cout<<"Case "<<++kase<<": maximum height = "<<maxans<<endl;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值