《趣学算法》动态规划 大卖场购物车1——01背包问题

2019-11-30

10:05:54

如何把背包问题画一幅DAG呢?这是自己最近很困惑的。想看看到底这个DAG是啥样!

 

 

#include <bits/stdc++.h>
#include <stdlib.h>
#include <stdio.h>
using namespace std;
#define maxn 10005
#define M 105
int c[M][maxn];
int w[M],v[M];
int x[M];//x[M]表示第i个物品是否放入购物车
int main(){
    int i,j,n,W;
    cout<<"请输入物品的个数: ";
    cin>> n;
    cout<<"请输入购物车的容量:";
    cin>>W;
    cout<<"请输入每个物品的重量w 和 价值 v,用空格分开:";
    for(int i=1;i<=n;++i){
        cin>>w[i]>>v[i];
    }
    for(i=0;i<=n;++i){
        c[i][0]=0;
    }
    for(j=0;j<=W;++j){
        c[0][j] = 0;
    }
    for(i=1;i<=n;++i){
        for(int j=1;j<=W;++j){
            if(j<w[i]){//当物品重量大于购物车容量时,不放入 
                c[i][j] = c[i-1][j];
            }
            else{
                c[i][j] = max(c[i-1][j],c[i-1][j-w[i]]+v[i]);
            }
        }
    }
    cout<<"装入购物车的最大价值为: "<<c[n][W]<<endl;
    //逆向构造最优解
    j = W;
    for(i=n;i>0;--i){
        if(c[i][j]>c[i-1][j]){
            x[i]=1;
            j -= w[i];
        }else{
            x[i] = 0;
        }
    }
    cout<<"装入购物车的物品为:"<<endl;
    for(int i=1;i<=n;++i){
        if(x[i]==1){
            cout<<i<<" ";
        }
    }
    system("pause");
    return 0;
     
} 

 

 优化成一维数组:

 

 逆序的关键是:如果是正序,则求f[v]时,f[0],...f[v-1]都已经改变过!里面存的不是i-1时刻的值。这样求f[v]时必定是错误的!

看一下错误的正序时的结果:

 

 这是正确的逆序时的结果:

 

 

#include <bits/stdc++.h>
#include <stdlib.h>
#include <stdio.h>
using namespace std;
#define maxn 10005
#define M 105
int  dp[maxn];//dp[i]表示当前已放入容量为j 的购物车获得的最大价值
int w[M],v[M];
int x[M];//x[i]表示第i个物品是否放入购物车
int i,j,n,W;//n表示n个物品,W表示购物车容量
void opt1(int n,int W){
    for(int i=1;i<=n;++i){
        for(j=W;j>0;--j){
            if(j>=w[i]){
                dp[j] = max(dp[j],dp[j-w[i]]+v[i]);
            }
        }
    }
} 
 
int main(){
    cout<<"请输入物品的个数: ";
    cin>>n;
    cout<<"请输入购物车的容量: ";
    cin>>W;
    cout<<"请依次输入每个物品的重量w和价值v,用空格分开: ";
    for(int i=1;i<=n;++i){
        cin>>w[i]>>v[i];
    }
    for(int j=1;j<=W;++j){
        dp[j] = 0;//初始化第0行为0; 
    }
    opt1(n,W);
    cout<<"装入购物车的最大价值为:"<<dp[W]<<endl;
    //测试dp[]数组结果
    for(j=1;j<=W;++j){
        cout<<dp[j]<<" "; 
    } 
    cout<<endl;
    system("pause");
    return 0;
     
} 

 

 

 

 

 

 

 

 

 

 

posted @ 2019-11-30 10:27  JasonPeng1  阅读(530)  评论(0编辑  收藏  举报