• 完全背包讲解


    完全背包讲解

    裸题洛谷P1616疯狂的采药

    本题为采药进化版   和采药的区别为  每种药材有无数多个  且可以多次采摘同种药材

    那么很容易想到完全背包

    下面放ac代码

    #include <stdio.h>
    #include <algorithm>
    #define rep(i,n) for(int i=1;i<=n;i++)
    using namespace std;
    typedef long long ll;
    int t,m,dp[100005],w[10005],v[10005];
    int main(int argc, char const *argv[])
    {
        scanf("%d%d",&t,&m);
        rep(i,m)
        {
            scanf("%d%d",&w[i],&v[i]);
        }
        rep(i,m)
        {
            for(int j=w[i];j<=t;j++)
            {
                dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
            }
        }
        printf("%d
    ",dp[t]);
        return 0;
    }

    那么

    整个代码精髓如下

    rep(i,m)
        {
            for(int j=w[i];j<=t;j++)
            {
                dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
            }
        }
    

    其中rep为for(int i=1;i<=m;i++)   (我比较懒  用define重新定义了下)

    那么我们可以看到  这段代码和01背包 一维数组优化只差一点点

    就是 内层for循环 使用的是顺序 而不是逆序

    其实我也不太理解

    那么就用我微薄的知识 简单解释一下吧

    我认为(逃

    和01背包的不同就在于 01背包类似于打表 每次一定要使用上组数据进行dp

    而完全背包不一样 因为可以重复选择 所以内层循环顺序可以使得使用本组数据dp 这样可以造成重复选择的结果(逃

    2019.4.22 更新

    遇到了需要把完全背包装满的问题

    要求背包必须装满  求最大值

         把dp[0]初始化为0,其余初始化为-infty

    要求背包必须装满  求最小值

         把dp[0]初始化为0,其余初始化为infty

    原因:

          初始化数组事实上就是在没有任何物品可以放入背包时的合法状态。如果要求背包恰好装满,那么此时只有容量为0的背包可以在什么也不装且价值为0的情况下被“恰好装满”,其它容量的背包均没有合法的解,属于未定义状态,应该被赋值为或者;如果背包并非必须装满,那么任何容量的背包都有一个合法解“什么也不装”,即0,所以可以把它们全部初始化为0。

     

    人十我百 人百我万
  • 相关阅读:
    最小生成树算法
    并查集
    背包问题
    木桶排序
    STL之vector
    STL中的queue用法与stack用法对比
    快速幂求模
    归并排序+典型例题(逆序对)
    负进制转换
    冒泡排序
  • 原文地址:https://www.cnblogs.com/bestcoder-Yurnero/p/10688562.html
Copyright © 2020-2023  润新知