http://acm.hdu.edu.cn/showproblem.php?pid=1069
输入几种方块,当方块的长宽小于下面那个时可以放在上面,求最大方块的高度。(方块可以无限)
每个方块有6种不同的状态,比如(10,20,30),(10,30,20)等等。30个方块的话,最多有180种形态。
思路:把所有的方块按照x从大到小排列,状态转化方程类似最大递增子序列。
if (dp[i].z + temp.z > dp[dp_i].z) dp[dp_i].z = dp[i].z;
#include<iostream>
#include<queue>
using namespace std;
struct box
{
int x;
int y;
int z;
friend bool operator < (box a, box b){
if (a.x == b.x)
return a.y < b.y;
return a.x < b.x;
}
}dp[200],box1;
int n;int x, y, z;
priority_queue<box> q;
int main(){
int time = 1;
while (cin >> n&&n){
for (int i = 0; i <= n * 3; i++){
dp[i].x = dp[i].y = dp[i].x = 0;
}
while (n--)
{
cin >> x >> y >> z;
box1 = { x, y, z }; q.push(box1);
box1 = { x, z, y }; q.push(box1);
box1 = { y, x, z }; q.push(box1);
box1 = { y, z, x }; q.push(box1);
box1 = { z, x, y }; q.push(box1);
box1 = { z, y, x }; q.push(box1);
}
int dp_i=1,max=0;
while (q.size()>0)
{
box temp = q.top(); q.pop();
//cout << temp.x << temp.y << " ";
dp[dp_i] = temp;
dp[dp_i].z = 0;
for (int i = 1; i < dp_i; i++){
if (dp[i].x <= temp.x) continue;
if (dp[i].y <= temp.y) continue;
if (dp[i].z + temp.z > dp[dp_i].z) dp[dp_i].z = dp[i].z;
}
dp[dp_i].z = dp[dp_i].z + temp.z;
if (dp[dp_i].z>max) max = dp[dp_i].z;
dp_i++;
}
cout << "Case "<<time++<<": maximum height = "<<max<< endl;
}
return 0;
}