UVA-624 CD (01 + backpack path memory)

Question is intended: to a broadcasting unit (backpack), then you play time period n (capacity), and the m corresponding to each tape, each tape has its own time (capacity), the maximum seek time can play and outputs the selected tape (maximum volume of the backpack can be stuffed and item selection), each tape only play once;

Thinking: This is the 0/1 knapsack problem (items can only be used once), while the contrast of the output to the selected items. We will use a two-dimensional dp to record (one dimension can not be recorded in the end the final choice of which items)

If dp [i] [J] == dp [I- 1] [jv [i]] + v [i], means that this is exactly in line with the path over the last transfer, you can get back the last article (because it is get items in reverse order, so they will reverse output)

 

Complete code:

#include <iostream>
#include <cstdio>
#include <cstring>
const int maxn =1e5;
int dp[30][maxn];
int v[maxn];
int ans[maxn];
using namespace std;
int main(){
    int n,m;
    while(~scanf("%d%d",&n,&m)){
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=m;i++){
            scanf("%d",&v[i]);
        }
        for(int i=1;i<=m;i++){
            for(int k= n;k>0;k--){
                dp[i][k] += max(dp[i-1][k-v[i]]+v[i],dp[i-1][k]);
                if(k<v[i]) dp[i][k] = dp[i-1][k];
            }
        }
        int cnt = 0;
        for(int i=m,j=n;i>0;i--){//下标与背包容量 
            if(j-v[i]>=0&&dp[i][j]== dp[i-1][j-v[i]]+v[i]){
                ans[cnt++] = v[i];//从v[i]处推导来
                j -= v[i]; 
            }
        }
        for(int i=cnt-1;i>=0;i--){
            cout<<ans[i]<<" ";
        }
        cout<<"sum:"<<dp[m][n]<<endl;
    
    }
}

 

                                     

Guess you like

Origin www.cnblogs.com/Tianwell/p/11223591.html