题意与分析
给定立方体(个数不限),求最多能堆叠(堆叠要求上方的方块严格小于下方方块)的高度。
表面上个数不限,问题是堆叠的要求决定了每个方块最多可以使用三次。然后就是对的方格序列用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;
}