「暑期訓練」「基礎DP」 Monkey and Banana (HDU-1069)

SamHX發表於2018-08-13

題意與分析

給定立方體(個數不限),求最多能堆疊(堆疊要求上方的方塊嚴格小於下方方塊)的高度。
表面上個數不限,問題是堆疊的要求決定了每個方塊最多可以使用三次。然後就是對3n的方格序列用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;
}

相關文章