zoukankan      html  css  js  c++  java
  • HDU1069Monkey and Banana(DP)

    题目连接

    解题报告:

    各种错误,各种纠正。。自我感觉对DP的理解入门些了。

    第一种思路是从i结点出发所能达到的最大高度,状态转移方程为dp[i] = dim[i]+max{dp[j]}, 其中G[i][j]=1,即j能放在i上。

     AC代码如下:

    View Code
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define MAXN 91
    
    struct{
        int x, y, z;
    }dim[MAXN*3];
    
    int dp[MAXN], G[MAXN][MAXN], _index;
    
    void _swap(int *a, int *b){
        int t = *a;
        *a = *b; *b = t;
    }
    
    void _sort(int *a, int *b, int *c){
        if(*a > *b) _swap(a, b);
        if(*a > *c) _swap(a, c);
        if(*b > *c) _swap(b, c);
    }
    
    int _max(int a, int b){
        return a > b ? a : b;
    }
    
    void _assi(int a, int b, int c){
        dim[_index].x = a;
        dim[_index].y = b;
        dim[_index++].z = c;
    }
    
    int d(int i){
        if(dp[i] > 0) return dp[i];
        int j;
        for(j=1; j<_index; j++){
            if(G[i][j]) dp[i] = _max(dp[i], d(j));
        }
        dp[i] += dim[i].z;
        return dp[i];
    }
    
    int main(){
        int cnt, n, i, j, x, y, z;
        cnt = 0;
        while(scanf("%d", &n) == 1 &&n != 0){
            _index = 1; cnt++;
            memset(G, 0, sizeof(G));
            memset(dp, 0, sizeof(dp));
            for(i=1; i<=n; i++){
                scanf("%d %d %d", &x, &y, &z);
                _sort(&x, &y, &z);
                _assi(x, y, z);
                if(z != y) _assi(x, z, y);  //这里赋值的同时去掉重复的。当然也可以不去。
                if(x != y) _assi(y, z, x);
            }
            for(i=1; i<_index; i++){
                for(j=1; j<_index; j++){
                    if(dim[i].x > dim[j].x && dim[i].y > dim[j].y) G[i][j] = 1;
                }
            }
            for(i=1; i<_index; i++)
                dp[i] = d(i);
            int ans = 0;
            for(i=1; i<_index; i++) if(ans < dp[i]) ans = dp[i];
            printf("Case %d: maximum height = %d\n", cnt, ans);
        }
        return 0;
    }

    第二种是从到i结点所能达到的最大高度,状态转移方程为dp[i] = dim[i]+max{dp[j]}, 其中G[j][i] = 1,即i能放在j上。

    首先,让在输入数据的时候要保证结构体中的x>=y,然后再对这些数据进行排序,如果两者之间的x相等, 就进行y的二级排序。如此就能保证能够盛放i的长方体如果存在的话那么一定在dim[0 ~ i-1]中。省去了G这个二维数组。

    AC代码如下。

    View Code
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define MAXN 91
    
    struct Dim{
        int x, y, z;
    }dim[MAXN*3];
    
    int dp[MAXN], _index;
    
    int _max(int a, int b){
        return a > b ? a : b;
    }
    
    void _assi(int a, int b, int c){
        dim[_index].x = a > b ? a : b;
        dim[_index].y = a > b ? b : a;
        dim[_index++].z = c;
    }
    
    int cmp(const struct Dim *a, const struct Dim *b){ //竟然能这么用。。
        if(a->x != b->x) return b->x - a->x;
        else return b->y - a->y;
    }
    
    int main(){
        int cnt, n, i, j, x, y, z, ans;
        cnt = 0;
        
        while(scanf("%d", &n) == 1 &&n != 0){
            _index = 0; cnt++;
            memset(dp, 0, sizeof(dp));
            
            for(i=0; i<n; i++){
                scanf("%d %d %d", &x, &y, &z);
                _assi(x, y, z); //这里没有排除3个数存在2个或者3个有重复数字的情况,不过不影响
                _assi(x, z, y);
                _assi(y, z, x);
            }
            qsort(dim, _index, sizeof(dim[0]), cmp);
            
            dp[0] = dim[0].z;
            for(i=1; i<_index; i++){    //dp
                ans = 0;
                for(j=i-1; j>=0; j--){
                    if(dim[j].x > dim[i].x && dim[j].y >dim[i].y)
                        if(ans < dp[j]) ans = dp[j];
                }
                dp[i] = ans+dim[i].z;
            }
            ans = 0;
            for(i=0; i<_index; i++) if(ans < dp[i]) ans = dp[i];
            printf("Case %d: maximum height = %d\n", cnt, ans);
        }
        return 0;
    }
  • 相关阅读:
    java开发环境
    堆栈方法区的创建
    Jmeter- 笔记8
    Jmeter- 笔记7
    Jmeter- 笔记6
    Jmeter- 笔记5
    Jmeter- 笔记4
    Jmeter- 笔记3
    Jmeter- 笔记2
    Jmeter- 笔记1
  • 原文地址:https://www.cnblogs.com/tanhehe/p/2910650.html
Copyright © 2011-2022 走看看