hdu1069 Monkey and Banana (最长上升子序列变形)(dp)

Monkey and Banana

链接:hdu1069

问题描述

一组研究人员正在设计一个测试猴子智商的实验。他们会把一根香蕉挂在屋顶上,同时给猴子提供一些积木。如果猴子够聪明的话,它应该能够够到香蕉,把一个积木放在另一个积木的上面,建一个塔,然后爬上去得到它最喜欢的食物。
研究人员有n种积木,每种积木的数量都是无限的。每一个i型块都是一个具有线性尺寸(xi, yi, zi)的矩形实体。一个物体可以被重新定向,这样它的三个维度中的任意两个都可以确定基座的维度,另一个维度是高度。
他们想要通过堆叠石块来确保最高的塔能够到达屋顶。问题在于,在建立一个塔,一个块只能被放置在另一个块只要上层块的两个基本维度都严格小于相应的基本维度较低的块,因为必须有一些猴子踩空间。这意味着,例如,面向具有相同大小基座的块不能堆叠。
你的工作是编写一个程序,确定猴子可以用给定的积木建造的最高塔的高度。

输入

输入文件将包含一个或多个测试用例。每个测试用例的第一行包含一个整数n,
表示下列数据集中不同块的个数。n的最大值为30。
下面n行中的每一行都包含三个整数,表示值xi、yi和zi。
输入被n的0(0)值终止。

输出

对于每个测试用例,以“case case: maximum height = height”格式打印一行,其中包含用例编号(从1开始依次编号)和可能的最高塔的高度。

Sample Input

1
10 20 30
2
6 8 10
5 5 5
7
1 1 1
2 2 2
3 3 3
4 4 4
5 5 5
6 6 6
7 7 7
5
31 41 59
26 53 58
97 93 23
84 62 64
33 83 27
0

Sample Output

Case 1: maximum height = 40
Case 2: maximum height = 21
Case 3: maximum height = 28
Case 4: maximum height = 342

分析:

类似求最长上升子序列
最简单的求最长上升子序列只需要判断一维大小就行了。
但是这题需要长和宽都比前面的大。
解决方法是先给一维排序保证递增,然后另一维求最长上升子序列就行了。
比如给长度递增排序,求宽度的最长上升子序列。
但是相邻的长方体长度可能相同所以判断的时候不仅要判断宽度而且长度也要一起判断(保证严格递增)
(另外这题求的是高度不是最长序列的长度,这个只要稍微改改就行了)

code:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<cmath>
#include<algorithm>
typedef long long ll;
const int inf=0x3f3f3f3f;
const int inn=0x80808080;
using namespace std;
const int maxm=1005;
struct Node{
    int a,b,c;
}a[maxm];
int d[maxm];//选到i时候的最大高度
int n;
int cnt;
int cas=1;
int cmp(Node a,Node b){
        return a.a<b.a;
}
int main(){
    while(cin>>n&&n){
        memset(d,0,sizeof d);
        cnt=0;
        for(int i=1;i<=n;i++){
            int aa,bb,cc;//长方体翻转之后有6种
            cin>>aa>>bb>>cc;
            a[++cnt].a=aa;//1
            a[cnt].b=bb;
            a[cnt].c=cc;
            a[++cnt].a=aa;//2
            a[cnt].b=cc;
            a[cnt].c=bb;
            a[++cnt].a=bb;//3
            a[cnt].b=aa;
            a[cnt].c=cc;
            a[++cnt].a=bb;//4
            a[cnt].b=cc;
            a[cnt].c=aa;
            a[++cnt].a=cc;//5
            a[cnt].b=bb;
            a[cnt].c=aa;
            a[++cnt].a=cc;//6
            a[cnt].b=aa;
            a[cnt].c=bb;
        }
        sort(a+1,a+cnt+1,cmp);
        int ans=0;
        for(int i=1;i<=cnt;i++){
            d[i]=a[i].c;
            for(int j=1;j<i;j++){
                if(a[j].a<a[i].a&&a[j].b<a[i].b){
                    d[i]=max(d[i],d[j]+a[i].c);
                }
            }
            ans=max(ans,d[i]);
        }
//        for(int i=1;i<=cnt;i++){//调试
//            cout<<a[i].a<<' '<<a[i].b<<' '<<d[i]<<endl;
//        }
        printf("Case %d: ",cas++);
        printf("maximum height = %d\n",ans);
    }
    return 0;
}


猜你喜欢

转载自blog.csdn.net/weixin_44178736/article/details/94621338