题目地址:
http://poj.org/problem?id=2241
题意:
给定N中方块,给定他们的长宽高,然后每一种方块的个数都为无限个。将任意数目的方块叠起来(但是要满足叠在一起的方块中,上面的方块的长和宽必须都小于下面方块的长和宽),问这些方块最多能叠多高。
思路:
DP求解。对Blocks的先按照X降级,再按照Y降级排序,可转化为最长公共子序列问题,即求子序列权值之和最大。可化为图算法,较笨。
#include <iostream>
#include <algorithm>
#include <string.h>
using namespace std;
#define MAX_SIZE 300
struct Block{
int x;
int y;
int height;
};
int nums[3];
Block blocks[MAX_SIZE];
bool cmp( Block a, Block b ){
if( a.x == b.x )
return a.y > b.y;
return a.x > b.x;
}
int main()
{
int case_num = 0;
while( true ){
case_num += 1;
int num;
cin >> num;
if( num == 0 ) break;
int index = 0;
for( int i = 0; i < num; ++i ){
cin >> nums[0] >> nums[1] >> nums[2];
int x = max( max( nums[0], nums[1] ), nums[2] );
int z = min( min( nums[0], nums[1] ), nums[2] );
int y = nums[0] + nums[1] + nums[2] - x - z;
blocks[index].x = x;
blocks[index].y = y;
blocks[index].height = z;
index++;
blocks[index].x = x;
blocks[index].y = z;
blocks[index].height = y;
index++;
blocks[index].x = y;
blocks[index].y = z;
blocks[index].height = x;
index++;
}
sort( blocks, blocks + index, cmp );
for( int i = 0; i < index; ++i ){
int max_height = 0;
for( int j = 0; j < i; ++j ){
if( blocks[j].y > blocks[i].y && blocks[j].x > blocks[i].x ){
max_height = max( max_height, blocks[j].height );
}
}
blocks[i].height += max_height;
}
int max_height = 0;
for( int i = 0; i < index; ++i ){
max_height = max( max_height, blocks[i].height );
}
cout << "Case " << case_num <<": maximum height = " << max_height << endl;
}
return 0;
}
POJ 2241 The Tower of Babylon,布布扣,bubuko.com
原文:http://blog.csdn.net/u011659057/article/details/27570551