zoukankan      html  css  js  c++  java
  • 《趣学算法》动态规划 大卖场购物车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;
         
    } 
  • 相关阅读:
    vue -resource 文件提交提示process,或者拦截处理
    利用vue写一个复选框的组件
    webpack处理媒体文件(图片/视频和音频)
    函数——惰性函数
    函数——函数的节流与防抖
    函数——箭头函数&自执行函数(二)
    js重点——作用域——作用域分类及变量提升
    js重点——作用域——内部原理
    js之数据类型(对象类型——单体内置对象——JSON)
    js之数据类型(对象类型——单体内置对象——Math)
  • 原文地址:https://www.cnblogs.com/JasonPeng1/p/11961516.html
Copyright © 2011-2022 走看看