• 回溯法(二)——0-1背包问题


    回溯法其实就是暴力,这个题目就是暴力的n层for(2次)循环。

      问题1、给定背包容量w,物品数量n,以及每个物品的重量wi,求背包最多能装多少多重的物品。
      问题2、给定背包容量w,物品数量n,以及每个物品的重量wi、价值vi,求背包最多能装多少价值的物品。
      这是一个基本的0-1背包问题,每个物品有两种状态(0:不装、1:装),总共有n步,所以可以用回溯法来解决,复杂度是O(2^n)。

    C++版代码如下
    #include <iostream>
    #include <math.h>
    #include <cstring>
    using namespace std;
    
    #define MAXSIZE 256
    
    int maxWeight = -9999;
    
    // 回溯法解决0-1背包问题(其实可以暴力(n层for循环),回溯法也是n层for循环,即复杂度是O(2^n))
    void basePackage(int stuff[], int curState, int state, int curWeight, int weight){
        // 如果装满了(其实应该是接近装满了)或者已经“走完”所有物品
        if(curState == state || curWeight == weight){
            if(curWeight > maxWeight)
                maxWeight = curWeight;
            return ;
        }
    
        // 不装
        basePackage(stuff, curState + 1, state, curWeight + 0, weight);
        // 装
        if(curWeight + stuff[curState] <= weight)
            basePackage(stuff, curState + 1, state, curWeight + stuff[curState], weight);
    }
    
    // 回溯法解决0-1背包问题(其实可以暴力(n层for循环),回溯法也是n层for循环,即复杂度是O(2^n))
    // 背包升级问题回溯法解决(加入背包的价值)
    void secPackage(int weight[], int value[], int curV, int curW, int weightLimit, int curS, int n){
        // 如果背包总重量等于背包限制
        if(curW == weightLimit || curS == n){
            if(curV > maxWeight)
                maxWeight = curV;
            return ;
        }
    
        // 不装
        secPackage(weight, value, curV, curW, weightLimit, curS + 1, n);
        if(curW + weight[curS] <= weightLimit)
            // 装
            secPackage(weight, value, curV + value[curS], curW + weight[curS], weightLimit, curS + 1, n);
    }
    
    int main(int argc, char* argv[]){
    
        // 总重量,物品个数
        int w, n;
        cin>>w>>n;
        int a[MAXSIZE + 1];
        for(int i = 0; i < n; i++)
            cin>>a[i];
        basePackage(a, 0, n, 0, w);
        cout<<maxWeight<<endl;
        return 0;
    }
    
  • 相关阅读:
    每日总结
    每日总结
    每日总结
    10.30
    10.29
    10.28
    10.27
    10.26
    10.25
    10.24
  • 原文地址:https://www.cnblogs.com/flyingrun/p/13484060.html
Copyright © 2020-2023  润新知