HDU 1069&&HDU 1087 (DP 最长序列之和)

H - Super Jumping! Jumping! Jumping!
Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u
Appoint description: 

Description

Nowadays, a kind of chess game called “Super Jumping! Jumping! Jumping!” is very popular in HDU. Maybe you are a good boy, and know little about this game, so I introduce it to you now. 



The game can be played by two or more than two players. It consists of a chessboard(棋盘)and some chessmen(棋子), and all chessmen are marked by a positive integer or “start” or “end”. The player starts from start-point and must jumps into end-point finally. In the course of jumping, the player will visit the chessmen in the path, but everyone must jumps from one chessman to another absolutely bigger (you can assume start-point is a minimum and end-point is a maximum.). And all players cannot go backwards. One jumping can go from a chessman to next, also can go across many chessmen, and even you can straightly get to end-point from start-point. Of course you get zero point in this situation. A player is a winner if and only if he can get a bigger score according to his jumping solution. Note that your score comes from the sum of value on the chessmen in you jumping path. 
Your task is to output the maximum value according to the given chessmen list. 
 

Input

Input contains multiple test cases. Each test case is described in a line as follow: 
N value_1 value_2 …value_N 
It is guarantied that N is not more than 1000 and all value_i are in the range of 32-int. 
A test case starting with 0 terminates the input and this test case is not to be processed. 
 

Output

For each case, print the maximum according to rules, and one line one case. 
 

Sample Input

3 1 3 2
4 1 2 3 4
4 3 3 2 1
0
 

Sample Output

4 10 3
 
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace  std;
const int maxn=1005;
int value[maxn];
int dp[maxn];
int main(){
     int n;
     //scanf("%d",&n);
     while(scanf("%d",&n)!=EOF){
           if(n==0)
            break;
           for(int i=1;i<=n;i++){
               scanf("%d",&value[i]);
               dp[i]=value[i];
           }
           int ans=-1;
           for(int i=1;i<=n;i++){
               for(int j=1;j<i;j++){
                   if(value[i]>value[j]&&dp[i]<dp[j]+value[i])
                       dp[i]=dp[j]+value[i];

               }
            ans=max(ans,dp[i]);
           }
        printf("%d
",ans);
     }
     return 0;
}
I - Monkey and Banana
Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u
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
 
//每个格子最多3个状态,也就是高最多有3种,也就是一共有N*3 最多90个格子,但是X和Y可以对调,那么就最多180个,我对180个格子对X从小到大排序,X相等,Y就重小到大排序,那么这个问题就可以转换成类似求最大递增子序列问题一样思路的DP,DP[i]表示第i个格子时的最大值,dp[i+1]就是从前i个中找符合条件的最大的一个加上去,因为,重楼必须X越来越小,反过来就是X越来越大,我已经保证了X是递增的,所以这样DP是对的!C++代码如下:
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=200;
struct node{
  int x,y,z;
}dp[maxn];
bool cmp(const struct node t1,const struct node t2){
     if(t1.x!=t2.x)
        return t1.x<t2.x;
     return t1.y<t2.y;
}
int main(){
     int cas=1;
    int n;
    while(scanf("%d",&n)!=EOF){
        int cnt=0;
        if(n==0)
            break;
        int tx,ty,tz;
        for(int i=1;i<=n;i++){
            scanf("%d%d%d",&tx,&ty,&tz);
            dp[cnt].x=tx,dp[cnt].y=ty,dp[cnt].z=tz,cnt++;
            dp[cnt].x=tx,dp[cnt].y=tz,dp[cnt].z=ty,cnt++;
            dp[cnt].x=ty,dp[cnt].y=tx,dp[cnt].z=tz,cnt++;
            dp[cnt].x=ty,dp[cnt].y=tz,dp[cnt].z=tx,cnt++;
            dp[cnt].x=tz,dp[cnt].y=tx,dp[cnt].z=ty,cnt++;
            dp[cnt].x=tz,dp[cnt].y=ty,dp[cnt].z=tx,cnt++;
        }
        sort(dp,dp+cnt,cmp);

        for(int i=0;i<cnt;i++){
                int tmp=-1;
            for(int j=0;j<i;j++){
                if((((dp[i].x>dp[j].x)&&(dp[i].y>dp[j].y))||((dp[i].x>dp[j].y)&&(dp[i].y>dp[j].x)))&&(dp[j].z>tmp)){
                    tmp=dp[j].z;
                }
            }
            if(tmp!=-1)
            dp[i].z+=tmp;
        }
           int ans=-1;
           for(int i=0;i<cnt;i++){
              ans=max(ans,dp[i].z);

           }

        printf("Case %d: maximum height = %d
",cas++,ans);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/13224ACMer/p/4990110.html