洛谷P1048 典型01背包问题
写在前面的话
蒟蒻在学习诸多图论算法之前,实际上没学过dp!
强说是学过也是只学了01背包,今天就来温习一下……
DP是啥?
动态规划(Dynamic Programming,DP)是运筹学的一个分支,是求解决策过程最优化的过程。
这是官方的解释,不过蒟蒻更喜欢把它的原理称作:
把计算结果记住。
实际上,我们可能已经早就见过动态规划了!它有很多别的名字,比如:
- 记忆化搜索
- 剪枝
- 用空间换时间
- 带备忘录(memo)的递归
发现了什么?我们很早就接触过动态规划!
这么一说,动态规划不是很难了吧!
动态规划的核心在状态转移方程,它的作用……本蒟蒻是这样理解的:
促进局部最优解向全局最优解发展
01背包DP
我们来仔细讲一下背包dp
题目传送门
代码:
#include<bits/stdc++.h>
using namespace std;
int t,m;//m<=100 物品个数;t<=1000 包包容量;
int times[101],values[101];
int dp[101][1001];//dp[i][j] means 以j为容量的包包,在前i个物品中进行放入的最大价值
int main(){
scanf("%d %d",&t,&m);
for(int i=1;i<=m;i++){
scanf("%d %d",×[i],&values[i]);
}
for(int i=1;i<=m;i++){
for(int j=1;j<=t;j++){
if(j>=times[i]){
dp[i][j]=max(dp[i-1][j],dp[i-1][j-times[i]]+values[i]);
}else{
dp[i][j]=dp[i-1][j];
}
}
}
cout<<dp[m][t];
return 0;
}
在阅读以下内容前请至少认真阅读一遍代码!
我们在这里将题中所给的各种采药时间视为占包包的空间就好了哈~
首先来看一下dp数组什么意思:
int dp[101][1001];//dp[i][j] means 以j为容量的包包,在前i个物品中进行放入的最大价值
假设我们有以下几个物品:
我们建立起对应的dp数组:
首先对表格第一行进行分析,我们可以看到,当只有物品1时,考虑的无非是放与不放的问题,我们发现物品1占用1个空间,若背包大小从1-5均可放入背包。
表格更新:
我们对第二行进行分析,此时我们有1和2两个物品可供选择,但是!我们发现2占空间为3!所以当背包空间在3以下时,2肯定放不进去,此时,我们只能将上方那个格子里的值给他平移下来。因为此时你既然无法放下新的这个,旧的也不能丢。别管上面那个是0还是不是0,平移下来一定是当前状态下最优解。
那么在3及以后,我们就要开始考虑是否要放入了。
发现,当包包空间为3时,我们只能要么只放一个1,要么只放一个2,换句话说,我们此时要比较上方那个格子的状态和加入这个物品前的最优解的值加上本物品的值的大小关系来进行决策。
加入这个物品前的最优解的值加上本物品的值这个怎么得到?
容易发现,根据最优解的原则,一个背包加上这个物品正好满了,这叫加入这个物品前的最优解。
于是乎,我们得到了一个状态转移方程!
dp[i][j]=max(dp[i-1][j],dp[i-1][j-times[i]]+values[i]);//times指的是占的空间,values指的是本物品价值
这行代码就是我们的状态转移方程。
根据以上我们总结出01背包核心思路:
- 如果当前背包容量\(<\)需决策物品的占的空间
- 直接平移同一列的上一个决策。
- 否则
- 执行状态转移方程,进行决策。
表格更新:
表格更新:
表格更新:
可以发现,最终dp[m][t]就是全局最优解。
写在最后
由于蒟蒻实在太弱,所以肯定讲的不是很好,有疏漏的地方。
蒟蒻过几天还想写一个有关最长上升子序列的题解……
完结撒花
洛谷P1048 典型01背包问题的更多相关文章
- 动态规划 洛谷P1048 [NOIP2005 普及组] 采药
洛谷P1048 [NOIP2005 普及组] 采药 洛谷的一个谱架-的题目,考的是01背包问题,接下来分享一下我的题解代码. AC通过图: 我的代码: 1 //动态规划 洛谷P1048 [NOIP20 ...
- 洛谷 P1048 采药【裸01背包】
题目描述 辰辰是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师.为此,他想拜附近最有威望的医师为师.医师为了判断他的资质,给他出了一个难题.医师把他带到一个到处都是草药的山洞里对他说:" ...
- 洛谷P1048 采药
题目OJ地址 https://www.luogu.org/problemnew/show/P1048 https://vijos.org/p/1104 题目描述辰辰是个天资聪颖的孩子,他的梦想是成为世 ...
- [转]POJ3624 Charm Bracelet(典型01背包问题)
来源:https://www.cnblogs.com/jinglecjy/p/5674796.html 题目链接:http://bailian.openjudge.cn/practice/4131/ ...
- 洛谷P1048采药题解
题目 这是一个裸的01背包,因为题目中没说可以采好多次,不多说上代码, #include<iostream> using namespace std; int main() { int n ...
- 洛谷P1404 平均数 [01分数规划,二分答案]
题目传送门 平均数 题目描述 给一个长度为n的数列,我们需要找出该数列的一个子串,使得子串平均数最大化,并且子串长度>=m. 输入输出格式 输入格式: N+1行, 第一行两个整数n和m 接下来n ...
- 洛谷P1048采药
这道题一看就知道是01背包,我门用f[i]来表示时间剩余i时的最大的价值 一共只有两种选择取或者不取,可以得到方程式f[i]=max(f[i],f[i-a[i]]+v[i])(a[i]是表示时间,v[ ...
- 洛谷 P1048 采药
采药 01背包模板题. #include <iostream> #include <cstdio> using namespace std; //Mystery_Sky //一 ...
- 通过洛谷P2639看01背包
题目描述 Bessie像她的诸多姊妹一样,因为从Farmer John的草地吃了太多美味的草而长出了太多的赘肉.所以FJ将她置于一个及其严格的节食计划之中.她每天不能吃多过H ( <= H &l ...
- 洛谷P1048 采药 二维dp化一维
题目描述 辰辰是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师.为此,他想拜附近最有威望的医师为师.医师为了判断他的资质,给他出了一个难题.医师把他带到一个到处都是草药的山洞里对他说:“孩子,这个 ...
随机推荐
- 齐博x2向上滚动特效
要实现图中圈起来的向上滚动特效,大家可以参考下面的代码 <!--滚动开始--> <style type="text/css"> .auto-roll{ he ...
- 《Java并发编程的艺术》读书笔记:二、Java并发机制的底层实现原理
二.Java并发机制底层实现原理 这里是我的<Java并发编程的艺术>读书笔记的第二篇,对前文有兴趣的朋友可以去这里看第一篇:一.并发编程的目的与挑战 有兴趣讨论的朋友可以给我留言! 1. ...
- 支持JDK19虚拟线程的web框架,之二:完整开发一个支持虚拟线程的quarkus应用
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 本篇是<支持JDK19虚拟线程的web ...
- letcode刷题记录-day03-罗马转整数
题目 罗马转整数 题目描述 罗马数字包含以下七种字符: I, V, X, L,C,D 和 M. 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 1000 例如, 罗马数字 ...
- Datatable 数据源
数据源类型 Datatable可以使用三种基本的JavaScript数据类型作为数据源 数组(Arrays[]) 对象(objects{}) 实例(new myclass()) 目前使用过的为前两种, ...
- 孙荣辛|大数据穿针引线进阶必看——Google经典大数据知识
大数据技术的发展是一个非常典型的技术工程的发展过程,荣辛通过对于谷歌经典论文的盘点,希望可以帮助工程师们看到技术的探索.选择过程,以及最终历史告诉我们什么是正确的选择. 何为大数据 "大 ...
- JDK源码分析实战系列-PriorityQueue
完全二叉树 一棵深度为k的有n个结点的二叉树,对树中的结点按从上至下.从左到右的顺序进行编号,如果编号为i(1≤i≤n)的结点与满二叉树中编号为i的结点在二叉树中的位置相同,则这棵二叉树称为完全二叉树 ...
- 原来用 MySQL 也可以做全文检索
我是风筝,公众号「古时的风筝」,专注于 Java技术 及周边生态. 文章会收录在 JavaNewBee 中,更有 Java 后端知识图谱,从小白到大牛要走的路都在里面. 有朋友聊到他们的系统中要接入全 ...
- python(牛客)试题解析3 - 困难
导航 一.找到已经最大承重的背包内如何放入最大价值的物品的最优解 二.查找一个字符串中包含另外一个字符串(可打乱顺序)的次数三.计算正整数数组从头走到最后一个成员所需的最小步骤四.计算字符串非严格递增 ...
- Centos安装Nodejs简单方式
Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时.本文主要讲的是如何在Linux即Centos上安装Nodejs的简单方式,有比设置环境变量更加简单的方式,那就是设 ...