当前位置: 首页 > news >正文

[学习笔记]背包问题(一)

01背包

N件物品和一个容量为V的背包.第i件物品体积为C_i,价值为W_i.

求背包最大价值.

f[i][j]表示前i种物品体积为j的最大价值,

f[i][j]=max(f[i-1][j],f[i-1][j-C_i]+W_i).

时间复杂度O(VN).

  • 优化空间复杂度

f[j]表示体积为j的最大价值,

f[j]=max(f[j],f[j-C_i]+W_i)(从大到小枚举j).

 

多重背包

N件物品和一个容量为V的背包。i种物品最多有M_i件可用,体积为C_i,价值为W_i.求背包最大价值.

f[i][j]表示前i种物品体积为j的最大价值,

f[i][j]=max(f[i-1][j-C_i\;\times\;k]+W_i\;\times\;k)(0\;\leq\;k\;\leq\;M_i)

时间复杂度O(VMN).

  • 二进制拆分

M_i拆成2^0,2^1,2^2...2^k,M_i-$\sum_{i=0}^{k}{2^i}$$(\sum_{i=0}^{k}{2^i}<M_i\;\leq\;\sum_{i=0}^{k+1}{2^i})$,

则在其中任意选取多个数,其和$\leq$M_i;

[1,M_i]间的数都可以通过选取其中多个数得到.

证明:

因为每个十进制数都可拆成二进制数,2^0,2^1,2^2...2^k分别代表二进制某一位上的1,

所以[1,$\sum_{i=0}^{k}{2^i}$]间的数都可以取到.

加上M_i-$\sum_{i=0}^{k}{2^i}$后,[M_i-$\sum_{i=0}^{k}{2^i}$+1,M_i]间的数都可以取到.

因为M_i\;\leq\;$\sum_{i=0}^{k+1}{2^i},即M_i\;\leq\;2^{k+2}-1,

所以M_i-2\;\times\;2^{k+1}+1\;\leq\;0,即M_i<2\;\times\;(2^{k+1}-1)=$2\;\times\;\sum_{i=0}^{k}{2^i}$.

所以[1,$\sum_{i=0}^{k}{2^i}$]\cap[M_i-$\sum_{i=0}^{k}{2^i}$+1,M_i]=[1,M_i].

例题

Description

设有1g,2g,3g,5g,10g,20g的砝码各若干枚(其总重\leq100000)要求:计算用这些砝码能称出的不同重量的个数,但不包括一个砝码也不用的情况。

Input

一行,包括六个正整数a_1,a_2,a_3,a_4,a_5,a_6,表示1g砝码有a_1个,2g砝码有a_2个...20g砝码有a_6个。相邻两个整数之间用单个空格隔开。

Output

的形式输出,其中N为可以称出的不同重量的个数。

Sample Input

1 1 0 0 0 0

Sample Output

Total=3 

Solution

多重背包二进制拆分+注意输出格式。

#include<cmath>
#include<ctime>
#include<stack>
#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define N 105
#define M 100005
using namespace std;
int a[7]={0,1,2,3,5,10,20};
int w[N],n,ans;bool f[N][M];
inline void init(){    
    for(int i=1,s,k;i<=6;++i){
        scanf("%d",&s);k=s;
        for(int j=1;k>=j;j<<=1,k>>=1){
            w[++n]=j*a[i];s-=j;
        }
        if(s) w[++n]=s*a[i];
    }
    f[0][0]=true;
    for(int i=1;i<=n;++i){
        for(int j=0;j<w[i];++j)
            f[i][j]=f[i-1][j];
        for(int j=w[i];j<M;++j)
            f[i][j]=(f[i-1][j]||f[i-1][j-w[i]]);
    }
    for(int j=1;j<M;++j)
        if(f[n][j]) ++ans;
    printf("Total=%d\n",ans);
}
int main(){
    freopen("weight.in","r",stdin);
    freopen("weight.out","w",stdout);
    init();
    fclose(stdin);
    fclose(stdout); 
    return 0;
}

  • 单调队列优化

观察式子f[i][j]=max(f[i-1][j-C_i\;\times\;k]+W_i\;\times\;k)(0\;\leq\;k\;\leq\;M_i),

每一个mod~C_i的值相同的j可以用单调队列进行优化.

例题 bzoj1531

 

完全背包

N件物品和一个容量为V的背包.每种物品都有无限件可用,第i件物品体积为C_i,价值为W_i.求背包最大价值.

f[i][j]表示前i种物品体积为j的最大价值.

f[i][j]=max(f[i-1][j-C_i\;\times\;k]+W_i\;\times\;k).

时间复杂度O(N^2V)

  • 优化时间复杂度

f[i][j]=max(f[i-1][j],f[i][j-C_i]+W_i).

例题 bzoj1618

转载于:https://www.cnblogs.com/AireenYe/p/6106563.html

相关文章:

  • SQL 基础语法(一)
  • HTTP慢速DOS(slow http denial of service attack)
  • PAT甲题题解-1104. Sum of Number Segments (20)-(水题)
  • Java 8 Lambda表达式,让你的代码更简洁
  • 使用scrapy创建工程
  • 文件属性
  • 插入排序
  • python核心编程第六章练习--6.5.d
  • python 迭代器和生成器
  • java---构造器
  • PAT甲题题解-1096. Consecutive Factors(20)-(枚举)
  • 汇编、c语言、c++的一些想法。
  • cocos2dx-lua_修改源码流程(cocos2dx-3.10、win7、Cocos Code IDE1.2)
  • HTML5全屏(Fullscreen)API详细介绍
  • 如何解决流程开发中SheetRadioButtonList页面取值问题
  • 【vuex入门系列02】mutation接收单个参数和多个参数
  • ➹使用webpack配置多页面应用(MPA)
  • 2017 年终总结 —— 在路上
  • 30天自制操作系统-2
  • Android系统模拟器绘制实现概述
  • Angular4 模板式表单用法以及验证
  • angular学习第一篇-----环境搭建
  • Cookie 在前端中的实践
  • C学习-枚举(九)
  • DOM的那些事
  • Effective Java 笔记(一)
  • java概述
  • miniui datagrid 的客户端分页解决方案 - CS结合
  • PAT A1120
  • ViewService——一种保证客户端与服务端同步的方法
  • Vue 重置组件到初始状态
  • 山寨一个 Promise
  • 设计模式走一遍---观察者模式
  • 提醒我喝水chrome插件开发指南
  • 微信端页面使用-webkit-box和绝对定位时,元素上移的问题
  • 一个SAP顾问在美国的这些年
  • 自制字幕遮挡器
  • 【运维趟坑回忆录】vpc迁移 - 吃螃蟹之路
  • #{}和${}的区别?
  • #NOIP 2014# day.1 T3 飞扬的小鸟 bird
  • (c语言版)滑动窗口 给定一个字符串,只包含字母和数字,按要求找出字符串中的最长(连续)子串的长度
  • (二)JAVA使用POI操作excel
  • (附源码)spring boot车辆管理系统 毕业设计 031034
  • (机器学习的矩阵)(向量、矩阵与多元线性回归)
  • (原)本想说脏话,奈何已放下
  • (转)Linux整合apache和tomcat构建Web服务器
  • *_zh_CN.properties 国际化资源文件 struts 防乱码等
  • .NET Core 实现 Redis 批量查询指定格式的Key
  • .NET 服务 ServiceController
  • .net 设置默认首页
  • .net专家(高海东的专栏)
  • @ModelAttribute 注解
  • [ MSF使用实例 ] 利用永恒之蓝(MS17-010)漏洞导致windows靶机蓝屏并获取靶机权限
  • [ABC294Ex] K-Coloring
  • [Android Pro] listView和GridView的item设置的高度和宽度不起作用