写在前面的话

蒟蒻在学习诸多图论算法之前,实际上没学过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",&times[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背包问题的更多相关文章

  1. 动态规划 洛谷P1048 [NOIP2005 普及组] 采药

    洛谷P1048 [NOIP2005 普及组] 采药 洛谷的一个谱架-的题目,考的是01背包问题,接下来分享一下我的题解代码. AC通过图: 我的代码: 1 //动态规划 洛谷P1048 [NOIP20 ...

  2. 洛谷 P1048 采药【裸01背包】

    题目描述 辰辰是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师.为此,他想拜附近最有威望的医师为师.医师为了判断他的资质,给他出了一个难题.医师把他带到一个到处都是草药的山洞里对他说:" ...

  3. 洛谷P1048 采药

    题目OJ地址 https://www.luogu.org/problemnew/show/P1048 https://vijos.org/p/1104 题目描述辰辰是个天资聪颖的孩子,他的梦想是成为世 ...

  4. [转]POJ3624 Charm Bracelet(典型01背包问题)

    来源:https://www.cnblogs.com/jinglecjy/p/5674796.html 题目链接:http://bailian.openjudge.cn/practice/4131/ ...

  5. 洛谷P1048采药题解

    题目 这是一个裸的01背包,因为题目中没说可以采好多次,不多说上代码, #include<iostream> using namespace std; int main() { int n ...

  6. 洛谷P1404 平均数 [01分数规划,二分答案]

    题目传送门 平均数 题目描述 给一个长度为n的数列,我们需要找出该数列的一个子串,使得子串平均数最大化,并且子串长度>=m. 输入输出格式 输入格式: N+1行, 第一行两个整数n和m 接下来n ...

  7. 洛谷P1048采药

    这道题一看就知道是01背包,我门用f[i]来表示时间剩余i时的最大的价值 一共只有两种选择取或者不取,可以得到方程式f[i]=max(f[i],f[i-a[i]]+v[i])(a[i]是表示时间,v[ ...

  8. 洛谷 P1048 采药

    采药 01背包模板题. #include <iostream> #include <cstdio> using namespace std; //Mystery_Sky //一 ...

  9. 通过洛谷P2639看01背包

    题目描述 Bessie像她的诸多姊妹一样,因为从Farmer John的草地吃了太多美味的草而长出了太多的赘肉.所以FJ将她置于一个及其严格的节食计划之中.她每天不能吃多过H ( <= H &l ...

  10. 洛谷P1048 采药 二维dp化一维

    题目描述 辰辰是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师.为此,他想拜附近最有威望的医师为师.医师为了判断他的资质,给他出了一个难题.医师把他带到一个到处都是草药的山洞里对他说:“孩子,这个 ...

随机推荐

  1. LcdToos如何实现PX01自动调Flicker及VCOM烧录

    准备工作: LcdTools+PX01点亮需调Flicker的屏:F118 Flicker探头,用于自动Flicker校准测量,F118连接PX01上电后,探头屏会提示零点校准,此时需盖住探头窗口再按 ...

  2. 3.pytest断言assert

    pytest使用的python自带的断言assert关键字,和unittest封装的assert断言不一样 原理:用来测试某个断言条件,如果断言条件为True,则程序将继续正常执行:但如果断言条件为假 ...

  3. GNN 101

    GNN 101 姚伟峰 http://www.cnblogs.com/Matrix_Yao/ GNN 101 Why Graph无处不在 Graph Intelligence helps It's t ...

  4. Android 跨进程渲染

    本项目用于验证 Android 是否能够跨进程渲染 View,最终实现了在子进程创建WebView,主进程显示的功能. 一.跨进程渲染的意义 有一些组件比如 WebView 如果在主进程初始化,会大大 ...

  5. python 队列(QUEUE)

    QUEUE python中多线程编程的数据结构 基本FIFO队列 class Queue.Queue(maxsize=0) 先进先出,maxsize为队列中能存放的数据个数上限. import Que ...

  6. java学习之springboot

    0x00前言 呀呀呀时隔好久我又来做笔记了,上个月去大型保密活动了,这里在网上看了一些教程如果说不是去做java开发我就不做ssm的手动整合了采用springboot去一并开发. Spring Boo ...

  7. (译)TDD(测试驱动开发)的5个步骤

    原文:5 steps of test-driven development https://developer.ibm.com/articles/5-steps-of-test-driven-deve ...

  8. 【笔记】CF1659E AND-MEX Walk 及相关

    题目传送门 位运算 设题目中序列 \(w_1,w_1\& w_2,w_1\& w_2\& w_3,\dots,w_1\& w_2\& \dots \& ...

  9. SpringCloud(十一)- 秒杀 抢购

    1.流程图 1.1 数据预热 1.2 抢购 1.3 生成订单 (发送订单消息) 1.4 订单入库 (监听 消费订单消息) 1.5 查看订单状态 1.6 支付 (获取支付链接 ) 1.7 支付成功 微信 ...

  10. 第一章:使用函数绘制matplotlib的图表组成元素

    1.绘制直线图 1 # ============================展现变量的趋势变化========================== 2 import matplotlib.pypl ...