- > 动规讲解基础讲解一——01背包(模板)
作为动态规划的基础,01背包的思想在许多动规问题中会经常出现,so,熟练的掌握01背包的思路是极其重要的;
v = (2,2,3)
w = (1,2,3)
可能你已经想到了,考虑“性价比”,先选取“性价比”高的。性价比怎么定义呢?用价值除以重量!先选取单位重量价值最大的物品试试?
v = (2,3,4)
w = (3,4,5)
假设我们已经知道了全部的f(i-1,*)的值,如何求f(i,*),换句话说我们有了状态表示还不够,如何求出递推式?
如果我们要选取第i件物品,那么前i – 1件物品必须要达到j - wi且价值最大。由我们对f的定义,有f(i,j) = f(i-1,j - wi) + vi, 那么我们究竟选不选第i件物品呢?只好看哪个大了值大了,所以由
那么初值是什么呢?f(0,*),一件物品也不选的时候,显然重量只能是0,其他的重量都不存在,我们用负无穷来表示不可能,因为求的是最大价值嘛。
那么,我们整理一下我们的递推式子和初值:
优化?我们看一下这个递推式子核心就是f(i,j) = max(f(i – 1, j) , f(i-1,j - wi) + vi), 看一下f(i,*)只与f(i-1,*)相关,再仔细看看我们的第维j,只和更小的值相关,我们可以省掉一维i,然后倒着循环j,用旧的值更新新的值,这时f一部分是旧的值f(i-1,*),一部分是新的值f(i,*)。更具体地说小于j地是旧值,其余是新值。
核心伪代码:
f() =
f(..m) = -∞
for i = to n do
for j = m downto wi do
f(j) = max(f(j), f(j - wi))
endfor
endfor
所求结果是max{f(0..m)}
注意我们循环j只到wi,因为再小的j会导致我们无法选择第i件物品,这时我们直接使用不用第i件物品的旧值就好啦。简单吧?
那么现在,时间复杂度时不变的,空间复杂度降低O(m)了。
们尝试换一种状态表示? 我们令f(i,j)表示决定了前i件物品,总重量不超过j时能获得的最大价值。仔细想想递推式是不变的,那么初值呢?如果初值不变,f就没变化了……i= 0时,总重量时0,又因为0不超过任何整数,所以根据定义初值是f(0,*) = 0
那么最终结果呢?根据定义,最终结果是f(n,m)而没有必要再一串数里取最大了。可见即使递推式相同,初值不同也会定义不同的函数,请不要忽略初值的作用啊。同样我们可以优化掉第一维。
核心伪代码:
初值f(..m) =
for i = to n do
for j = m downto wi do
f(j) = max(f(j), f(j - wi))
endfor
endfor
所求结果是f(m)
再换一种状态表示?刚才讲了,我们有重量和价值两个指标,那么我们令f(i,j)是决定了前i件物品,总价值恰好是j时的最小重量,那么经过类似的分析,我们可以写出这样的初值和递推式:
{0(i=0∩j=0)
f(i,j)= {∞(i=0∩j>0)
{f(i−1,j)(i>0∪j<vi)
{max(f(i−1,j),f(i−1,j−wi)+vi)(i>0∪j>vi)
那结果是什么呢?
根据定义结果是max{x| f(n, x) <= m}, 同样我们可以优化掉一维的空间复杂度。那么时间复杂度是什么呢? O(n * sum(vi)) sum(vi)表示所有vi的和,也是第二维有意义的大小。
f(0,1.. sum(vi))) = 0
可见,动态规划问题状态表示十分灵活,不同的状态表示会有不同的解决方法。努力取发现吧!
第1行,2个整数,N和W中间用空格隔开。N为物品的数量,W为背包的容量。(1 <= N <= 100,1 <= W <= 10000)
第2 - N + 1行,每行2个整数,Wi和Pi,分别是物品的体积和物品的价值。(1 <= Wi, Pi <= 10000)
输出可以容纳的最大价值。
3 6
2 5
3 8
4 9
14
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,w[],d[],m,f[];
int main()
{
cin>>n>>m;
for(int i=;i<=n;i++) cin>>w[i]>>d[i];
for(int i=;i<=n;i++)
for(int j=m;j>=w[i];j--)
f[j]=max(f[j],f[j-w[i]]+d[i]);
cout<<f[m];
}
如果对你有所帮助,别忘了加好评哦;么么哒!!下次见!88
- > 动规讲解基础讲解一——01背包(模板)的更多相关文章
- HDU 2602 - Bone Collector - [01背包模板题]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2602 Many years ago , in Teddy’s hometown there was a ...
- 01背包模板、全然背包 and 多重背包(模板)
转载请注明出处:http://blog.csdn.net/u012860063 贴一个自觉得解说不错的链接:http://www.cppblog.com/tanky-woo/archive/2010/ ...
- 【洛谷P2722 USACO】 总分 01背包模板
P2722 总分 Score Inflation 题目背景 学生在我们USACO的竞赛中的得分越多我们越高兴. 我们试着设计我们的竞赛以便人们能尽可能的多得分,这需要你的帮助 题目描述 我们可以从几个 ...
- P2871 [USACO07DEC]手链Charm Bracelet(01背包模板)
题目传送门:P2871 [USACO07DEC]手链Charm Bracelet 题目描述 Bessie has gone to the mall's jewelry store and spies ...
- - > 动规讲解基础讲解三——混合背包(背包模板)
将01背包,完全背包,和多重完全背包问题结合起来,那么就是混合三种背的问题 根据三种背包的思想,那么可以得到混合三种背包的问题可以这样子求解 for(int i=1; i<=N; ++i) if ...
- POJ 3624 Charm Bracelet(0-1背包模板)
http://poj.org/problem?id=3624 题意:给出物品的重量和价值,在重量一定的情况下价值尽可能的大. 思路:经典0-1背包.直接套用模板. #include<iostre ...
- 解题报告:hdu2602 Bone collector 01背包模板
2017-09-03 15:42:20 writer:pprp 01背包裸题,直接用一维阵列的做法就可以了 /* @theme: 01 背包问题 - 一维阵列 hdu 2602 @writer:ppr ...
- HDU 3339 In Action【最短路+01背包模板/主要是建模看谁是容量、价值】
Since 1945, when the first nuclear bomb was exploded by the Manhattan Project team in the US, the n ...
- 洛谷 P2871 [USACO07DEC]手链Charm Bracelet && 01背包模板
题目传送门 解题思路: 一维解01背包,突然发现博客里没有01背包的板子,补上 AC代码: #include<cstdio> #include<iostream> using ...
随机推荐
- LPS HDOJ 4745 Two Rabbits
题目传送门 /* 题意:一只兔子顺时针跳,另一只逆时针跳,跳石头权值相等而且不能越过起点 LPS:这道就是LPS的应用,把环倍增成链,套一下LPS,然而并不能理解dp[i][i+n-2] + 1,看别 ...
- Android 性能优化(24)*性能工具之「Traceview,dmtracedump」Profiling with Traceview and dmtracedump :记录并查看函数调用栈*
Profiling with Traceview and dmtracedump In this document Traceview Layout Traceview工具界面介绍 T ...
- RaspberryPi cProfile使用
使用sudo python -m cProfile -o 1.cprof your.py生成cprof文件 windows下安装snakeviz:pip install -i https://pypi ...
- leetcode692 Top K Frequent Words
思路: 堆.实现: #include <bits/stdc++.h> using namespace std; class Solution { public: inline bool c ...
- 北工大2017校赛 1101:要打车的FanZzz
题目链接: http://bjutacm.openjudge.cn/lianxi/1101/ 思路: 二分 + 二分图最大匹配. 开始的时候我想直接用最小费用流模型,后来发现这样是错误的.因为这道题实 ...
- 本地编译全志R系列的步骤7(Ubuntu 17.04非长期支持版本)
本地编译全志R系列的步骤7(Ubuntu 17.04非长期支持版本) 2017/6/29 13:49 0.获取全志R系列的Android源码包: 请通过渠道/代理商/方案公司获取全志R系列的Andro ...
- JavaScript中逻辑运算符的使用
逻辑运算符用于对一个或多个布尔值进行逻辑运算.在JavaScript中有3个逻辑运算符,如下表所示. 运算符 描述 示例 && 逻辑与 a && b //当a和b都为 ...
- SVN的三种merge方式【转】
SVN的merge操作是为了保证主干(trunk)和分支(branch)同步,merge方式有: 1.Merge a range of revisions(合并一个范围的版本) 2.Reintegra ...
- Expectation-Maximization(EM) 算法
Expectation-Maximization 算法是统计学中用来给带隐含变量的模型做最大似然(和最大后验概率)的一种方法.EM 的应用特别广泛,经典的比如做概率密度估计用的 Gaussian Mi ...
- Javascript(IE快捷键操作),ASP技巧
1. oncontextmenu="window.event.returnValue=false" 将彻底屏蔽鼠标右键 <table border oncontextmenu ...