HDU 1069 dp最长递增子序列

B - Monkey and Banana

Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u

Submit Status Practice HDU 1069

Appoint description:

Description

A group of researchers are designing an experiment to test the IQ of a monkey. They will hang a banana at the roof of a building, and at the mean time, provide the monkey with some blocks. If the monkey is clever enough, it shall be able to reach the banana by placing one block on the top another to build a tower and climb up to get its favorite food.

The researchers have n types of blocks, and an unlimited
supply of blocks of each type. Each type-i block was a rectangular solid
with linear dimensions (xi, yi, zi). A block could be reoriented so
that any two of its three dimensions determined the dimensions of the
base and the other dimension was the height.

They want to make sure that the tallest tower possible by
stacking blocks can reach the roof. The problem is that, in building a
tower, one block could only be placed on top of another block as long as
the two base dimensions of the upper block were both strictly smaller
than the corresponding base dimensions of the lower block because there
has to be some space for the monkey to step on. This meant, for example,
that blocks oriented to have equal-sized bases couldn‘t be stacked.

Your job is to write a program that determines the height of the tallest tower the monkey can build with a given set of blocks.

Input

The input file will contain one or more test cases. The first line of each test case contains an integer n,

representing the number of different blocks in the following data set. The maximum value for n is 30.

Each of the next n lines contains three integers representing the values xi, yi and zi.

Input is terminated by a value of zero (0) for n.

Output

For each test case, print one line containing the case number (they are
numbered sequentially starting from 1) and the height of the tallest
possible tower in the format "Case case: maximum height = 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

每个格子可以形成6种状态,最多有180种状态,,,,,,,对X,Y作为判断条件进行判断,累加Z值

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
struct node{
    int x,y,z;
}que[200];
int dp[200];
int tot;

void addedge(int x,int y,int z){
     que[tot].x=x;
     que[tot].y=y;
     que[tot++].z=z;

      que[tot].x=x;
     que[tot].y=z;
     que[tot++].z=y; 

     que[tot].x=y;
     que[tot].y=x;
     que[tot++].z=z;

     que[tot].x=y;
     que[tot].y=z;
     que[tot++].z=x;

     que[tot].x=z;
     que[tot].y=x;
     que[tot++].z=y; 

     que[tot].x=z;
     que[tot].y=y;
     que[tot++].z=x;
}

bool cmp(struct node t1,struct node t2){
     if(t1.x!=t2.x)
         return t1.x>t2.x;
     else if(t1.x==t2.x&&t1.y!=t2.y)
         return t1.y>t2.y;
     else
         return t1.z>t2.z;
}

int main(){
   int n;
   int cas=1;
   while(scanf("%d",&n)!=EOF){
       if(!n)
           break;
       memset(dp,0,sizeof(dp));
        tot=1;
       int x,y,z;
       for(int i=0;i<n;i++){
           scanf("%d%d%d",&x,&y,&z);
           addedge(x,y,z);
       }
       sort(que+1,que+tot+1,cmp);
       dp[1]=que[1].z;
       for(int i=2;i<tot;i++){
           dp[i]=que[i].z;
          for(int j=i-1;j>=1;j--){
              if(que[i].x<que[j].x&&que[i].y<que[j].y&&dp[i]<dp[j]+que[i].z)
                  dp[i]=dp[j]+que[i].z;
          }
       }
       int ans=-1;
       for(int i=1;i<tot;i++)
           ans=max(ans,dp[i]);
        printf("Case %d: maximum height = %d\n",cas++,ans);
   }
   return 0;
}
时间: 2024-08-07 16:58:58

HDU 1069 dp最长递增子序列的相关文章

hdu 1025 dp 最长上升子序列

1 //Accepted 4372 KB 140 ms 2 //dp 最长上升子序列 nlogn 3 #include <cstdio> 4 #include <cstring> 5 #include <iostream> 6 using namespace std; 7 const int imax_n = 500005; 8 int dp[imax_n]; 9 int d[imax_n]; 10 int a[imax_n]; 11 int n; 12 int len

HDU 3998 Sequence (最长递增子序列+最大流SAP,拆点法)经典

Sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1666    Accepted Submission(s): 614 Problem Description There is a sequence X (i.e. x[1], x[2], ..., x[n]). We define increasing subsequ

HDU 1087 &amp;&amp; POJ 2533(DP,最长上升子序列).

~~~~ 两道题的意思差不多,HDU上是求最长上升子序列的和,而POJ上就的是其长度. 貌似还有用二分写的nlogn的算法,不过这俩题n^2就可以过嘛.. ~~~~ 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1087 http://poj.org/problem?id=2533 ~~~~ HDU1087: #include<cstdio> #include<cstring> #include<algorithm> #

动态规划(DP),最长递增子序列(LIS)

题目链接:http://poj.org/problem?id=2533 解题报告: 状态转移方程: dp[i]表示以a[i]为结尾的LIS长度 状态转移方程: dp[0]=1; dp[i]=max(dp[k])+1,(k<i),(a[k]<a[i]) #include <stdio.h> #define MAX 1005 int a[MAX];///存数据 int dp[MAX];///dp[i]表示以a[i]为结尾的最长递增子序列(LIS)的长度 int main() { int

Redraiment的走法(最长递增子序列问题的求解--dp问题)

输入描述: 输入多行,先输入数组的个数,再输入相应个数的整数 输出描述: 输出结果 输入例子: 6 2 5 1 5 4 5 输出例子: 3 提示 Example: 6个点的高度各为 2 5 1 5 4 5 如从第1格开始走,最多为3步, 2 4 5 从第2格开始走,最多只有1步,5 而从第3格开始走最多有3步,1 4 5 从第5格开始走最多有2步,4 5 所以这个结果是3. //最长递增子序列问题--动态规划问题 1 import java.util.*; 2 public class Test

Bridging signals POJ 1631(最长递增子序列dp)

原题 题目链接 题目分析 由题目知,如果能求出连接点的最长递增子序列,则可以把连接不在该序列中的点的线全部剪掉.而维护最长递增子序列可以用dp来做,考虑到相同长度的递增子序列末尾数字越小越好,可以这样定义dp,dp[i]长度为i的递增子序列的最小末尾值,初始化为INF,由于这个dp具有有序性,因此可以用二分来加快更新,每次遍历到值num[i],只需二分找出大于等于num[i]的更新之即可.最后从扫一遍dp数组即可得到最长长度. 代码 1 #include <iostream> 2 #inclu

POJ 2533 Longest Ordered Subsequence【最长递增子序列】【DP思想】

Longest Ordered Subsequence Time Limit : 4000/2000ms (Java/Other)   Memory Limit : 131072/65536K (Java/Other) Total Submission(s) : 6   Accepted Submission(s) : 1 Problem Description A numeric sequence of ai is ordered ifa1 < a2 < ... < aN. Let t

最长公共子序列(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的一个子序列. 考虑最长公共子序列问题如何分解成

[网络流24题]最长递增子序列问题

题目大意:给定长度为n的序列a,求:1.最长递增子序列长度:2.最多选出几个不相交的最长递增子序列:3.最多选出几种在除了第1个和第n个以外的地方不相交的最长递增子序列.(n<=1000) 思路:先倒着DP,求出f[i]表示以a[i]开头的最长的递增子序列长度,然后建图,若f[i]=最长递增子序列长度则S向i连1,若f[i]=1则i向T连1,若i<j且a[i]<a[j]且f[i]=f[j]+1则i向j连1,为保证每个点只被流一次,拆成入点和出点,流量限制1,跑最大流即可解决第二问,点1和