洛谷【P1048 采药】题解
分析:典型的01背包问题,设dp[i][j]为空间(也就是题面中的时间)是j的背包在装前i个物品(草药)所得的最大价值,v[i]为第i个物品的重量(采药的时间),w[i]为第i个物品(草药)的价值,则有:
当j>v[i]时,dp[i][j]=max{dp[i-1][j],dp[i-1][j-v[i]]+w[i]}
当j<=v[i]时,dp[i][j]=dp[i-1][j]
接下来,我们就来详细解析一下我们的前辈是怎样得到这个公式的。(知道的可以跳过)
假设我们现在有这样一组数据:
10 4
3 4
4 7
6 11
8 16
我们需要列一个表格,来模拟dp数组变化的过程。
如果你模拟的没错的话,表格最后会是这样的:

我们发现,dp[i][j]总比上面的dp[i-1][j]多(或相等),这是为什么呢?
因为,dp[i][j]表示的是空间是j的背包在装前i个物品所得的最大价值,少装一个物品(也有可能装的一样)不可能比多装一个物品的价值高。
因为上一行(dp[i-1][j])已经把能装的都装了,所以我们只需要考虑当前物品是否能装的下当前的背包就可以了。
所以,有了这个神奇的状态转移方程:
当j>v[i]时,f[i][j]=max{f[i-1][j],f[i-1][j-v[i]]+w[i]}
当j<=v[i]时,f[i][j]=f[i-1][j]
ok,说了这么多,终于到了大家期待的代码环节:
献上本蒟蒻的代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,m;
int w[105],v[105],dp[105][1005];
memset(dp,0,sizeof(dp));
int i,j;
scanf("%d %d",&m,&n);
for(i=1;i<=n;i++) scanf("%d %d",&v[i],&w[i]);
for(i=1;i<=n;i++)
{
for(j=0;j<=m;j++)
{
if(j<v[i]) dp[i][j]=dp[i-1][j];
else dp[i][j]=max(dp[i-1][j],dp[i-1][j-v[i]]+w[i]);
}
}
printf("%d\n",dp[n][m]);
return 0;
}
但是------------------
这个代码是能进行空间优化的!(虽然这道题不需要)
考虑到状态转移方程只对上一行(dp[i-1][j])进行操作,所以我们可以将dp数组从这样:
dp[105][1005]
变成这样:
dp[1005](详见代码)
这,就是传说中的滚动数组。
当然,优化了空间之后,中间的操作也需要一些特殊的操作。(详见代码)
献上本蒟蒻的滚动数组代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,m;
int w[105],v[105],dp[1005];
memset(dp,0,sizeof(dp));
int i,j;
scanf("%d %d",&m,&n);
for(i=1;i<=n;i++) scanf("%d %d",&v[i],&w[i]);
for(i=1;i<=n;i++)
for(j=m;j>=0;j--)
if(j>=v[i]) dp[j]=max(dp[j-v[i]]+w[i],dp[j]);
printf("%d\n",dp[m]);
return 0;
}
评测结果:
不加空间优化:

加滚动数组空间优化:

虽然好像没什么变化
洛谷【P1048 采药】题解的更多相关文章
- 洛谷P1048采药题解
题目 这是一个裸的01背包,因为题目中没说可以采好多次,不多说上代码, #include<iostream> using namespace std; int main() { int n ...
- 洛谷P1048 采药
题目OJ地址 https://www.luogu.org/problemnew/show/P1048 https://vijos.org/p/1104 题目描述辰辰是个天资聪颖的孩子,他的梦想是成为世 ...
- 洛谷P1048 采药 二维dp化一维
题目描述 辰辰是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师.为此,他想拜附近最有威望的医师为师.医师为了判断他的资质,给他出了一个难题.医师把他带到一个到处都是草药的山洞里对他说:“孩子,这个 ...
- 洛谷 P1048 采药【裸01背包】
题目描述 辰辰是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师.为此,他想拜附近最有威望的医师为师.医师为了判断他的资质,给他出了一个难题.医师把他带到一个到处都是草药的山洞里对他说:" ...
- 洛谷 P1048 采药
采药 01背包模板题. #include <iostream> #include <cstdio> using namespace std; //Mystery_Sky //一 ...
- 洛谷P1048采药
这道题一看就知道是01背包,我门用f[i]来表示时间剩余i时的最大的价值 一共只有两种选择取或者不取,可以得到方程式f[i]=max(f[i],f[i-a[i]]+v[i])(a[i]是表示时间,v[ ...
- 动态规划 洛谷P1048 [NOIP2005 普及组] 采药
洛谷P1048 [NOIP2005 普及组] 采药 洛谷的一个谱架-的题目,考的是01背包问题,接下来分享一下我的题解代码. AC通过图: 我的代码: 1 //动态规划 洛谷P1048 [NOIP20 ...
- 洛谷NOIp热身赛题解
洛谷NOIp热身赛题解 A 最大差值 简单树状数组,维护区间和.区间平方和,方差按照给的公式算就行了 #include<bits/stdc++.h> #define il inline # ...
- 洛谷P2827 蚯蚓 题解
洛谷P2827 蚯蚓 题解 题目描述 本题中,我们将用符号 ⌊c⌋ 表示对 c 向下取整. 蛐蛐国最近蚯蚓成灾了!隔壁跳蚤国的跳蚤也拿蚯蚓们没办法,蛐蛐国王只好去请神刀手来帮他们消灭蚯蚓. 蛐蛐国里现 ...
- 洛谷P1816 忠诚 题解
洛谷P1816 忠诚 题解 题目描述 老管家是一个聪明能干的人.他为财主工作了整整10年,财主为了让自已账目更加清楚.要求管家每天记k次账,由于管家聪明能干,因而管家总是让财主十分满意.但是由于一些人 ...
随机推荐
- python发送钉钉机器人脚本
#!/usr/bin/python# -*- coding: utf-8 -*-import requestsimport jsonimport sysimport os headers = {'Co ...
- css 设置div半透明 悬浮在页面底部 不随滚动条滚动
.action-button { width: 100%; background:rgba(0,0,0,0.7); position:fixed; bottom:; left:; z-index:; ...
- springMVC 数据模型相关注解 可注释类型 ModelAttribute SessionAttributes InitBinder
ModelAttribute 参数/方法SessionAttributes 类InitBinder 方法
- Q-Dir – 布局灵活的文件管理,强烈推荐
Q-dir 是轻量的文件管理器,特点鲜明,各种布局视图切换灵活,默认四个小窗口组成一个大窗口,操作快捷.软件虽小,却非常好用 下载地址: https://www.softwareok.com/?Dow ...
- 平时没有怎么用Excel做 加减乘除 计算,猛地发现,其实Excel 是一个很好的简单计算器
平时没有怎么用Excel做 加减乘除 计算,猛地发现,其实Excel 是一个很好的简单计算器
- 禁用 Ubuntu 18.04 Files 的 Type Ahead search 功能
. . . . . Ubuntu 的文件浏览器(Files)提供了一个搜索的功能,叫做“Type Ahead search”.即我们在文件浏览器中输入某个文件的名字时,Files 并不是将焦点定位在某 ...
- 拼接Sql语句小心得
在往数据库插入数据时,需要根据数据和数据库中的列信息进行拼接,在本篇文章中,输出小心得.使用语言为 python. 拼接原始列信息 比如待插入数据库列信息为 deptNo,dName, Locate, ...
- EasyNVR摄像机网页无插件直播方案H5前端构建之:bootstrap弹窗功能的实现方案与代码
前言介绍 在web前端的网页设计中,为了展示出简洁的网页风格和美观的效果,往往会使用弹窗效果在EasyNVR前端页面录像检索功能时,必然会播放录像,如果单独为播放录像文件排一个界面,用户在使用上会更加 ...
- svn"重新定位"提示版本库uuid不匹配
svn"重新定位"提示版本库 uuid不匹配: 版本库 "https://wolfcome110/svn/andon" 的 uuid是 "d52648 ...
- java核心技术(卷一)
一,java基本程序设计结构: 1,在网页中运行的 Java 程序称为 applet. 要使用 applet ,需要启用 Java 的 Web 浏览器执行字节码. 2,jdk安装目录下的 src.zi ...