• 回溯法 01背包


    代码:

    #include <iostream>
    using namespace std;
    
    const int M = 100; //设物品最多100个
    int n, MaxWight, SumValue;
    int wight[M], value[M], ans[M], a[M];
    
    void backtrack(int t, int Swight, int Svalue)
    {
        // cout << t << " " << Swight << " " << Svalue << endl; 调试的时候可以输出数据做参考
        if (t >= n)
        {
            if (SumValue < Svalue)
            {
                SumValue = Svalue;
                for (int i = 0; i < n; i++)
                    ans[i] = a[i];
            }
        }
        else
        {
            for (int i = 0; i <= 1; i++)
            {
                a[t] = i;
                Swight = Swight + i * wight[t];
                Svalue = Svalue + i * value[t];
                if (Swight <= MaxWight)
                {
                    backtrack(t + 1, Swight, Svalue);
                }
                else //实际重量大于最大重量时,从背包把物品拿出。
                {
                    Swight = Swight - i * wight[t];
                    Svalue = Svalue - i * value[t];
                }
            }
        }
    }
    
    int main()
    {
        cin >> n >> MaxWight;
        for (int i = 0; i < n; i++)
            cin >> value[i];
        for (int i = 0; i < n; i++)
            cin >> wight[i];
        backtrack(0, 0, 0);
        for (int i = 0; i < n; i++)
            cout << ans[i];
        cout << endl
             << SumValue << endl;
    
        return 0;
    }
    

    n 代表的是物品个数

    MaxWight 背包能装的最大体积

    SumValue 物品的最大价值

    ans 数组,最终选择方式

    a 数组,临时选择方式

     

    思路:物品只有两种选择,放或者不放,构造二叉树,n 个物品就是 n 层树,然后进行最优值更新。

     

    样例:

    图1

    背包构造出的二叉树如图1,顺序三从右边到左边,也就是先不放物品,然后再慢慢放进去。

    输入:

    3 30

    45 25 25

    16 15 15

    输出:

    0 1 1 :放进后面 2 件物品。 50 : 最大价值

     

     

    附回溯法搜索子集树模板:

    void backtrack(int k)
    {
        if(到达边界) 更新或者输出结果
        else
        {
            对于每一种可能进行操作(for循环 i)
            {
                if(限定条件合法)
                    backtrack(k+i);
            }
        }
        
    }
    
  • 相关阅读:
    2021.12.7
    2021.12.13(观察者模式c++)
    2021.12.05(echarts生成mysql表词云)
    2021.12.10(申请加分项)
    2021.12.10(课程总结)
    2021.12.11(Linux,yum错误,There are no enabled repos.)
    12月读书笔记02
    2021.12.12(springboot报ScannerException)
    2021.12.09
    centos国内镜像站
  • 原文地址:https://www.cnblogs.com/stul/p/10665008.html
Copyright © 2020-2023  润新知