zoukankan      html  css  js  c++  java
  • 百度之星资格赛 1004 度度熊的午饭时光 DP 打印路径

      题目链接: http://bestcoder.hdu.edu.cn/contests/contest_showproblem.php?cid=774&pid=1004

      题目大意: 一个0-1背包, 需要输出路径

      解题思路: 0-1背包很好求, 输出路径以前没有做过.......就是记录更新位置, 然后通过数组的跳跃间距求出到底取的是哪些点......

      代码: 自己代码, 没AC, 是什么玄学BUG, 我也懒得改了

    #include <iostream>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <map>
    #include <cstring>
    #include <iterator>
    #include <cmath>
    #include <algorithm>
    #include <stack>
    #include <deque>
    #include <map>
    
    #define lson l, m, rt<<1
    #define rson m+1, r, rt<<1|1
    
    
    const int maxn = 1e3 + 100;
    using namespace std;
    //const int INF = 0x3fffffff;
    int score[maxn];
    int cost[maxn];
    int dp[maxn][maxn]; // 前i个花费<=j时的最高得分
    int vis[maxn][maxn];
    int temp[maxn];
    int cnt;
    int main() {
        int t;
        scanf( "%d", &t );
        for( int cases = 1; cases <= t; cases++ ) {
            cnt = 0;
            int B;
            int N;
            scanf( "%d%d", &B, &N );
            for( int i = 1; i <= N; i++ ) {
                scanf( "%d%d", score+i, cost+i );
            }
            memset(dp, 0, sizeof(dp));
            memset(vis, 0, sizeof(vis));
            if( N == 0 || B == 0 ) {
                printf( "Case #%d:
    ",cases );
                printf( "0 0
    " );
                continue;
            }
            for( int i = 1; i <= N; i++ ) {
                for( int j = B; j >= 0; j-- ) {
                    dp[i][j] = dp[i-1][j];
                    if( j >= cost[i] ) {
                        if( dp[i-1][j-cost[i]]+score[i] > dp[i][j] ) {
                            dp[i][j] = dp[i-1][j-cost[i]]+score[i];
                            vis[i][j] = 1;
                        }
                    }
                }
            }
            int ans = 0;
            int i = N, j = B;
            while (i > 0 && j > 0)
            {
                if (vis[i][j] == 1)
                {
                    ans += cost[i];
                    j -= cost[i];
                }
                i--;
            }
            printf( "Case #%d:
    ", cases );
            printf( "%d %d
    ", dp[N][B], ans );
            i = N, j = B;
            while (i > 0 && j > 0)
            {
                if (vis[i][j] == 1)
                {
                    temp[cnt++] = i;
                    j -= cost[i];
                }
                i--;
            }
            sort( temp, temp + cnt);
            for( int i = 0; i < cnt; i++ ) {
                if( i == 0 ) printf( "%d", temp[i] );
                else printf( " %d", temp[i] );
            }
            printf( "
    " );
        }
        return 0;
    }
    View Code

      徐文栋的AC代码: 

    #include <bits/stdc++.h>
    using namespace std;
    
    typedef pair<int, int> pii;
    const int maxn = 110;
    const int maxm = 1010;
    int m, n;
    int v[maxn], w[maxn];
    int f[maxm];
    int path[maxn][maxm];
    vector<int> tmp;
    
    signed main() {
        // freopen("in", "r", stdin);
        int T, _ = 1;
        scanf("%d", &T);
        while(T--) {
            memset(path, 0, sizeof(path));
            memset(f, 0, sizeof(f));
            tmp.clear();
            scanf("%d%d",&m,&n);
            for(int i = 1; i <= n; i++) {
                scanf("%d%d",&v[i], &w[i]);
            }
            for(int i = 1; i <= n; i++) {
                for(int j = m; j >= w[i]; j--) {
                    if(f[j] < f[j-w[i]]+v[i]) {
                        f[j] = f[j-w[i]] + v[i];
                        path[i][j] = 1;
                    }
                }
            }
            printf("Case #%d:
    ", _++);
            int tot1 = 0, tot2 = 0;
            for(int i = n, j = m; i >= 1; i--) {
                if(path[i][j]) {
                    tot1 += v[i]; tot2 += w[i];
                    tmp.push_back(i);
                    j -= w[i];
                }
            }
            printf("%d %d
    ", tot1, tot2);
            sort(tmp.begin(), tmp.end());
            for(int i = 0; i < tmp.size(); i++) {
                printf("%d%c", tmp[i], i==tmp.size()-1?'
    ':' ');
            }
        }
        return 0;
    }
    View Code

      思考: 自己只会纯裸的0-1背包, 真的菜, 通过这道题又补了自己的知识点, 以后还是通过做题锻炼自己的思维,再补自己的知识点

  • 相关阅读:
    CKA-Kubernets(K8s) (一)
    CKA-docker 容器的管理
    CKA-docker 镜像的管理
    CKA-docker 基础
    开年自省系列—— 阅读完一本书《财务之路系列》 读书笔记
    Sublime开启VIM模式
    JavaScript 踩坑开始(ing...)
    代码思考题玩玩
    P2016 战略游戏-树形DP
    皇宫看守-树形DP
  • 原文地址:https://www.cnblogs.com/FriskyPuppy/p/7293959.html
Copyright © 2011-2022 走看看