• 动态规划背包问题


    0-1背包

    解决思路:

    每次尝试往背包里新加一个物品,如果装不下,则将体积组建增大。当能装下时候,用当前体积减去新装入的这个物品的体积,得到除了当前这个物品的体积,在之前的已知解中查找这个体积容纳的最大价值,用这个最大价值加上当前物品的价值就是新的最大价值。

    #include<iostream>
    #include<stdio.h>
    using namespace std;
    
    void Knapsack(int n,int c,int *w,int *p){
        int f[100][100];
        int i=0,j=0;
        for(i=1;i<=n;i++){  # n 是物品的个数,这一层循环尝试逐个添加物品
            for(j=1;j<=c;j++){  # j是当前体积,逐渐增加体积 ,观察体积变大后放入当前物品j之后价值的变化
                f[i][j]=f[i-1][j]; # i-1 是上一个物品, [j] 当前体积,f[i-1][j] 也就是上一个物品当前体积下的最大价值
                if(j>=w[i]){  # j 是当前体积, w[i] 是当前物品的体积,因为要往背包里放入当前物品,所以当前假定的体积要大于物品的体积
                    f[i][j]=max(f[i-1][j],f[i-1][j-w[i]]+p[i]);  # 如果能放下,要查找除掉当前物品的体积之后的体积能装的最大的价值, f[i-1][*] 是添加上一个物品的已知解空间, 
                    # w[i] 是当前物品的体积, j 是当前假设背包的体积 j-[w[i]] 也就是当前背包的体积去掉当前物品的体积, f[i-1][j-w[i]] 就是去掉当前物品体积后还剩下的体积装的最大价值
                    # f[i-1][j-w[i]]+p[i] 即是装上当前物品后的最大价值
                    # f[i-1][j] 是不转入当前物品的最大价值,一般不会取这个值,除非有物品价值为负数或者0
                }
            }
        }
    
        cout<<"背包能装的最大价值是:" << f[i-1][j-1] <<endl;
    }
    int main(){
        int n;
        int c;
    
        c=10;   //背包容量c
        n=5;    //物体个数n
        int w[6]={0,2,2,6,5,4};   //物品体积
        int p[6]={0,6,3,5,4,6};   //物品价值
        Knapsack(n,c,w,p);
    
    }
    

    分组背包

    分组背包与01背包的区别是,分组背包需要在一组商品中只能选择一个。
    一组商品中可以包含n个商品。在01背包中选择一个物品加入背包观察价值是否变化,在分组背包中,则是尝试将一组物品组个尝试加入背包,观察最大价值的是哪个。

    分组背包时间复杂度:

    \(O(n) = \sum\limits_{i=1}^{m} C*M[i]\)

    参数 说明
    C 容积
    M[i] 第i个分组中物品的个数
    m 分组个数

    如果背包的体积为C,物品的个数为N,则算法复杂度为:

    $ O(n) = C * N $

    参考:

  • 相关阅读:
    Rex 密钥认证
    MQTT协议之moquette 安装使用
    开源MQTT中间件:moquette
    Hazelcast入门简介
    Maven和Gradle对比
    rex 上传文件并远程执行
    myeclipse配置gradle插件
    ansible 新手上路
    CentOS release 6.5 (Final) 安装ansible
    spring boot 使用profile来分区配置
  • 原文地址:https://www.cnblogs.com/oaks/p/16420897.html
Copyright © 2020-2023  润新知