题目地址:
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