题目大意:输入若干种立方体(每种若干个),然后将立方体堆成一个塔,要求接触的两个面下底面的长宽分别严格大于上底面,求塔的最大高度。
解析:将每种立方体的各种摆放形式均视为不同的立方体,并存起来。再将所有立方体按照下底面的面积从小到大排序(因为在塔上面的立方体的底面积一定比下面的小),然后求该序列的最大上升子序列的高度。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 35 * 3;
struct Node {
int x,y,z;
}box[N];
int dp[N];
bool cmp(Node a,Node b) {
if(a.x != b.x) {
return a.x < b.x;
}else {
return b.y < b.y;
}
}
int main() {
int n,cas = 1;
int l[3];
while(scanf("%d",&n) != EOF && n) {
for(int i = 0; i < n*3; i += 3) {
scanf("%d%d%d",&l[0],&l[1],&l[2]);
sort(l,l+3);
box[i].x = l[0];
box[i].y = l[1];
box[i].z = l[2];
box[i+1].x = l[0];
box[i+1].y = l[2];
box[i+1].z = l[1];
box[i+2].x = l[1];
box[i+2].y = l[2];
box[i+2].z = l[0];
}
int maxx = 0;
sort(box,box+n*3,cmp);
memset(dp,0,sizeof(dp));
for(int i = 0; i < n*3; i++) {
dp[i] = box[i].z;
for(int j = 0; j <= i; j++) {
if(box[i].x > box[j].x && box[i].y > box[j].y) {
dp[i] = max(dp[i],dp[j] + box[i].z);
}
}
if(dp[i] > maxx) {
maxx = dp[i];
}
}
printf("Case %d: maximum height = %d\n",cas++,maxx);
}
return 0;
}
通过将立方体的不同摆放视为独立对象并排序,利用最长递增子序列算法求解最大塔高问题。
2075

被折叠的 条评论
为什么被折叠?



