5thweek.problem_B(zoj 1093) LIS

Description

一组研究人员正在设计一项实验,以测试猴子的智商。他们将挂香蕉在建筑物的屋顶,同时,提供一些砖块给这些猴子。如果猴子足够聪明,它应当能够通过合理的放置一些砖块建立一个塔,并爬上去吃他们最喜欢的香蕉。

研究人员有n种类型的砖块,每种类型的砖块都有无限个。第i块砖块的长宽高分别用xi,yi,zi来表示。 同时,由于砖块是可以旋转的,每个砖块的3条边可以组成6种不同的长宽高。

在构建塔时,当且仅当A砖块的长和宽都分别小于B砖块的长和宽时,A砖块才能放到B砖块的上面,因为必须留有一些空间让猴子来踩。

你的任务是编写一个程序,计算猴子们最高可以堆出的砖块们的高度。

Input

输入文件包含多组测试数据。

每个测试用例的第一行包含一个整数n,代表不同种类的砖块数目。n<=30.

接下来n行,每行3个数,分别表示砖块的长宽高。

当n= 0的时候,无需输出任何答案,测试结束。

Output

对于每组测试数据,输出最大高度。格式:Case 第几组数据: maximum height = 最大高度

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

题目分析:

1.定义一个结构体存储砖块的长宽高,每输入一个砖块的长宽高,由于砖块可以旋转,因此可以直接将此砖块的六种状态存进结构体数组。init(a,b,c);    init(a,c,b;

init(b,a,c);   init(b,c,a); init(c,a,b); init(c,b,a);

2.然后将此机构图数组按:长、宽、高从小到大排序。

3.状态转移

代码及简要分析:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 using namespace std;
 6 struct cuboid
 7 {
 8     int l,w,h;
 9 }cu[190];
10 int dp[190];
11
12 int k;
13 void init(int x,int y,int z)
14 {
15  cu[k].l=x; cu[k].w=y; cu[k].h=z; k++;
16 }
17 bool cmp(const cuboid &a,const cuboid &b)
18 {
19     if(a.l==b.l)
20     {
21         if(a.w==b.w)
22             return a.h<b.h;
23         //else
24         return a.w<b.w;
25     }
26     //else
27     return a.l<b.l;
28 }
29
30 int main()
31 {
32   int n,i,j,a,b,c,maxn,t=1;
33   while(cin>>n && n)
34   {
35       k=0,maxn=0;
36     for(i=0;i<n;i++)
37     {
38        scanf("%d%d%d",&a,&b,&c);
39        init(a,b,c);
40        init(a,c,b);
41        init(b,a,c);
42        init(b,c,a);
43        init(c,a,b);
44        init(c,b,a);
45     }
46     sort(cu,cu+k,cmp);
47    // for(i=0;i<k;i++)
48      //   cout<<cu[i].l<<"  "<<cu[i].w<<"  "<<cu[i].h<<endl;
49
50     for(i=0;i<k;i++)
51     {
52         dp[i]=cu[i].h;
53     }
54     for(i=1;i<k;i++)
55     {
56         for(j=0;j<i;j++)     //j<i且j=0开始,j不可等于i
57        {
58         if(cu[i].l>cu[j].l && cu[i].w>cu[j].w && dp[j]+cu[i].h>dp[i] )
59             {
60                 dp[i]=dp[j]+cu[i].h;
61                if(maxn<dp[i])
62                 maxn=dp[i];
63             }
64        }
65     }
66     printf("Case %d: maximum height = %d\n",t++,maxn);
67   }
68
69   return 0;
70 }
时间: 2024-08-05 13:25:15

5thweek.problem_B(zoj 1093) LIS的相关文章

ZOJ 1093

排序DP(相当于最长不下降子序列) 如果把一块砖块的所有6种摆放方式转化为6种不同的砖块: 即相当于有6n种砖块,然后按照一个方向从大到小排序: 再依次检查每一块与其下面的所有砖块是否满足摆放条件: 将每一块砖块放到塔中能够获得的最大高度记录到数组height[N]中: 则该数组中的最大值就是该题的解了: #include <iostream>#include <algorithm>#include "cstdio"using namespace std;#de

ZOJ 1093 &amp;&amp; NYoj16(DP)

~~~~ 两个题目大致类似,NYOJ上面那道题就是小白上的矩形嵌套啦. 都是先对长宽进行排序,然后逐层更新最大值(边更新边记录). 好了,不说了. 题目链接: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1093 http://acm.nyist.net/JudgeOnline/problem.php?pid=16 ~~~~ ZOJ1093: #include<cstdio> #include<cstring&

ZOJ 1093 Monkey and Banana

题目链接 题意:给你n个规格的砖块,告诉你它的长.宽.高,每种规格的砖都有无数块,长宽小的砖块(严格小于,不能等于)可以叠在长宽大的砖块上,问你最多能叠多高. 思路:告诉你一种规格的砖其实给了你三种规格的砖,因为砖是可以翻转的,长宽高可以变化的: 以长为第一变量,宽为第二变量,从大到小排序,这样垫在第n块砖下面的只能从前n-1块选择,选择最大值,累加高度即可. 代码如下: #include <stdio.h> #include <string.h> #include <ios

ZOJ1093 Monkey and Banana 【DP】

一.题目 ZOJ 1093 二.题目源程序 #include <stdio.h>//一个箱子有3种h..所以总共有3*n种高度.按面积从大到小排序 #include <stdlib.h> struct block { int x,y,z,h; }a[200]; int cmp(const void *a,const void *b)//快排,模版 { return ((struct block *)b)->x*((struct block *)b)->y - ((str

LIS ZOJ - 4028

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=4028 memset超时 这题竟然是一个差分约束 好吧呢 对于每一个a[i], l <= a[i] <= r 那么设一个源点s 使 l <= a[i] - s <= r  是不是就能建边了 然后对于每一个f[i] 如果前面有一个相等的f[j] 则肯定 a[i] <= a[j]  又能建边了 根据LIS的传递关系 对于每个f[i] 肯定是由上一个等级的传递

POJ3903 5thweek.problem_E LIS

Description The world financial crisis is quite a subject. Some people are more relaxed while others are quite anxious. John is one of them. He is very concerned about the evolution of the stock exchange. He follows stock prices every day looking for

最长公共子序列(LCS)、最长递增子序列(LIS)、最长递增公共子序列(LICS)

最长公共子序列(LCS) [问题] 求两字符序列的最长公共字符子序列 问题描述:字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列.令给定的字符序列X=“x0,x1,…,xm-1”,序列Y=“y0,y1,…,yk-1”是X的子序列,存在X的一个严格递增下标序列<i0,i1,…,ik-1>,使得对所有的j=0,1,…,k-1,有xij=yj.例如,X=“ABCBDAB”,Y=“BCDB”是X的一个子序列. 考虑最长公共子序列问题如何分解成

poj - 1093 - Formatting Text(dp)

题意:输入一段短文(所有字符总数不超过10000),要求格式化成两端对齐(每行长度为n,1 <= n <= 80)的方式输出并使得总坏值最小(一个空隙的坏值是这个空隙的空格总数减1后的平方),若有多种方案输出空格数字典序最小方案. 题目链接:http://poj.org/problem?id=1093 -->>状态:dp[i]表示从第i个单词开始到最后一个单词的最小总坏值(第i个单词是这一行的第1个单词) 状态转移方程:dp[i] = min(dp[i], dp[j + 1] +

zoj题目分类

饮水思源---zoj 转载自:http://bbs.sjtu.edu.cn/bbscon,board,ACMICPC,file,M.1084159773.A.html 注:所有不是太难的题都被归成了“简单题”,等到发现的时候已经太晚了,我太死脑筋 了……:( 有些题的程序我找不到了,555……:( SRbGa的题虽然都很经典……但是由于其中的大部分都是我看了oibh上的解题报告后做 的,所以就不写了…… 题目排列顺序没有规律……:( 按照个人感觉,最短路有的算做了DP,有的算做了图论. 有些比较