zoukankan      html  css  js  c++  java
  • 三种基本背包问题

    一、0/1背包问题

    问题描述:有n件物品和容量为m的背包 给出i件物品的重量以及价值 求解让装入背包的物品重量不超过背包容量 且价值最大 。
    特点:这是最简单的背包问题,特点是每个物品只有一件供你选择放还是不放。如果想不通代码就填表观察过程。

    输入:

    5 10
    2 6
    2 3
    6 5
    5 4
    4 6

    输出:

    15

      

    ① 二维解法
    设f[i][j]表示前 i 件物品 总重量不超过 j 的最大价值 可得出状态转移方程

    f[i][j]=max{f[i-1][j-a[i]]+b[i], f[i-1][j]}
    

    核心代码

        
    int f[100][100]={0}; 
    for(int i=1;i<=num;i++){ for(int j=capacity;j>=1;j--){ if(weight[i]<=j) {f[i][j]=max(f[i-1][j],f[i-1][j-weight[i]]+value[i]);} else f[i][j]=f[i-1][j]; } }

    表格:

    ②一维解法
    设f[j]表示重量不超过j公斤的最大价值 可得出状态转移方程

    f[j]=max{f[j], f[j−a[i]]+b[i]}
    

    核心代码

        
    int f[1000]={0};
    for(int i=1;i<=num;i++){ for(int j=capacity;j>=weight[i];j--){ f[j]=max( f[j],f[j-weight[i]]+value[i] ); } }

    循环的第二层

    为什么要从后往前循环!!!!
          因为吧,从后往前循环,每次取得状态不会和你之前取得状态重合,这样就符合01背包的要求,每种物品只取一次;不理解填表

    表格:

     完整代码:

    #include <bits/stdc++.h>
    using namespace std;
    int main(){
        int num,capacity;   // 第一行为n值和c值,表示n件物品和背包容量c
        cin>>num>>capacity;
        int weight[1000];
        int value[1000];
        for(int i=1;i<=num;i++){  //每行有两个数据,分别表示第i(1≤i≤n)件物品的重量和价值。
            cin>>weight[i]>>value[i];
        }
        
        int f[1000]={0}; //设f[j]表示重量不超过j公斤的最大价值 可得出状态转移方程f[j]=max{f[j], f[j-a[i]]+b[i]}
        for(int i=1;i<=num;i++){
            for(int j=capacity;j>=weight[i];j--){
                f[j]=max( f[j],f[j-weight[i]]+value[i] );
            }
        }
         
        cout<<f[capacity]<<endl;
        return 0;
    }

    二、完全背包问题

    问题描述:有n件物品和容量为m的背包 给出i件物品的重量以及价值 求解让装入背包的物品重量不超过背包容量 且价值最大 。
    特点:题干看似与01一样 但它的特点是每个物品可以无限选用

    设f[j]表示重量不超过j公斤的最大价值 可得出状态转移方程

    f[j] = maxj{f[j], f[j−a[i]]+b[i]}
    

    核心代码

        int f[1000]={0};
        for(int i=1;i<=num;i++){
            for(int j=weight[i];j<=capacity;j++){
                f[j]=max( f[j],f[j-weight[i]]+value[i] );
            }
        }

    循环的二层

    从前往后循环,每次取到的状态都会和前面的状态或多或少都有重叠,这样就刚好的满足了,每种物品无限取得要求了。

  • 相关阅读:
    git命令
    熟悉sql常用语句
    面试:django
    python面试基本题(你需要的)
    django的几种方法进行序列化(视图)
    阿布云代理ip
    了解Git操作
    django前后端交互
    面向对象
    mysql数据库基本操作
  • 原文地址:https://www.cnblogs.com/lvjingyuan/p/13958403.html
Copyright © 2011-2022 走看看