0-1背包 记录路径 UVA624

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Tianweidadada/article/details/82805749


 

题目大意:有一个固定长度的磁带,想要把CD放进去,空间利用率尽可能的高,每个磁带只能用一次。

01背包问题,就是把体积和重量看做了tracks和time,这里注意打印路径的方法 

#include<iostream>
#include<stdio.h>
#include<vector>
#include<map>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<set>
#include<cmath>
using namespace std;
typedef long long LL;
const int N = 5005;
LL dp[3005][N];
int cost[N];

int main()
    {
        int time,m; // n
        while(scanf("%d%d",&time,&m) != EOF){
            memset(dp,0,sizeof(dp));
            memset(cost,0,sizeof(cost));
            for(int i = 1; i <= m; ++i){
                scanf("%d",&cost[i]);
            }

            for(int i = 1; i <= m; ++i){
                for(int j = time; j >= 0; --j){
                    if(j < cost[i])  // 注意小于的情况
                        dp[i][j] = dp[i-1][j];
                    else{
                        dp[i][j] = max(dp[i-1][j],dp[i-1][j-cost[i]] + cost[i]);
                    }
                }
            }
            vector<int> res;
            int last = time;
            for(int i = m; i >= 1; --i){
                for(int j = last; j >= 0; --j){
                    if(j >= cost[i] && dp[i][j] == cost[i] + dp[i-1][j-cost[i]]){ // 注意 需要 j >= cost[i] 这个条件
                        res.push_back(cost[i]);
                        last = j-cost[i];
                        break;
                    }
                    else
                        break;
                }
            }
            for(int i = res.size()-1; i >= 0; --i){
                printf("%d ",res[i]);
            }
            printf("sum:%d\n",dp[m][time]);

        }


        return 0;
    }

猜你喜欢

转载自blog.csdn.net/Tianweidadada/article/details/82805749