• 背包问题------ 分类: ACM 2015-08-03 20:57 1人阅读 评论(0) 收藏


    对于背包问题,网上有很多博客= =,如果有不小心点进来的朋友,看到我挫逼的博文然后看不懂,可以自行百度一篇,其中本文的博文内
    容参照 http://blog.csdn.net/lyhvoyage/article/details/8545852#0-qzone-1-46291-d020d2d2a4e8d1a374a433f596ad1440
    那里讲的很详细
    01背包问题
    01背包问题的模型可以总结为在N件物品,体积为Vi,价值为Wi,然后有一个体积为V的背包,然后求背包最多能装多大价值的的物品

    for(int i=0;i<n;i++)
            {
                for(int j=V;j>=v[i];j--)
                {
                    dp[j]=max(dp[j],dp[j-v[i]]+w[i]);
                }
            }

    完全背包
    然后让我们把问题扩展一下,若物体不止拿一次,可以拿若干干次,那这个问题就变成完全背包问题
    代码其实和上面那个很像

    for(int i=0;i<n;i++)
            {
                for(int j=v[i];j<=V;j++)
                {
                    dp[j]=max(dp[j],dp[j-v[i]]+w[i]);
                }
            }

    多重背包“
    然后让我们作死再把问题变一下,物品的数量有限制= =然后怎么办捏,这个时候二进制就发挥它强大的功能,比如7的二进制是111,它可以分解为001,010,100这三个数可以组成任何小于等于7的数,而且不同的组合可以得到不同的数,所以根据这个原理,我们可以把这个问题转化为01背包问题,其实就是把多个物品用二进制分解为每一种物品都只有一个= =

    x代表物体的体积,y代表价值,z代表物体的个数
        scanf("%d %d %d",&x,&y,&z);
            for(int k=1;k<=z;k<<=1)
            {
                w[count]=x*k;
                v[count++]=y*k;  
                z=z-k;
            }
            if(z>0)//这步其实很容易遗漏
            {
                w[count]=z*x;
                v[count++]=z*y;
            }

    搞完那个二进制就可以直接用01背包来做啦

        for(int i=0;i<count;i++)
        {
            for(int j=W;j>=w[i];j--)
            {
                f[j]=max(f[j],f[j-w[i]]+v[i]);
            }
        }

    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    数据科学家成长指南(下)
    数据科学家成长指南(中)
    数据科学家成长指南(上)
    数据分析的职业规划
    2018的内容写作方向
    乱码 设置编码
    CI 如何获取get请求过来的数据
    ci 打印出常用的变量
    CI $_GET
    获取checkbox 组成字符串
  • 原文地址:https://www.cnblogs.com/NaCl/p/4700580.html
Copyright © 2020-2023  润新知