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

【洛谷 P1616】疯狂的采药 题解(动态规划+完全背包)

疯狂的采药

题目背景

此题为纪念 LiYuxiang 而生。

题目描述

LiYuxiang 是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师。为此,他想拜附近最有威望的医师为师。医师为了判断他的资质,给他出了一个难题。医师把他带到一个到处都是草药的山洞里对他说:“孩子,这个山洞里有一些不同种类的草药,采每一种都需要一些时间,每一种也有它自身的价值。我会给你一段时间,在这段时间里,你可以采到一些草药。如果你是一个聪明的孩子,你应该可以让采到的草药的总价值最大。”

如果你是 LiYuxiang,你能完成这个任务吗?

此题和原题的不同点:

1 1 1. 每种草药可以无限制地疯狂采摘。

2 2 2. 药的种类眼花缭乱,采药时间好长好长啊!师傅等得菊花都谢了!

输入格式

输入第一行有两个整数,分别代表总共能够用来采药的时间 t t t 和代表山洞里的草药的数目 m m m

2 2 2 到第 ( m + 1 ) (m + 1) (m+1) 行,每行两个整数,第 ( i + 1 ) (i + 1) (i+1) 行的整数 a i , b i a_i, b_i ai,bi 分别表示采摘第 i i i 种草药的时间和该草药的价值。

输出格式

输出一行,这一行只包含一个整数,表示在规定的时间内,可以采到的草药的最大总价值。

样例 #1

样例输入 #1

70 3
71 100
69 1
1 2

样例输出 #1

140

提示

数据规模与约定
  • 对于 30 % 30\% 30% 的数据,保证 m ≤ 1 0 3 m \le 10^3 m103
  • 对于 100 % 100\% 100% 的数据,保证 1 ≤ m ≤ 1 0 4 1 \leq m \le 10^4 1m104 1 ≤ t ≤ 1 0 7 1 \leq t \leq 10^7 1t107,且 1 ≤ m × t ≤ 1 0 7 1 \leq m \times t \leq 10^7 1m×t107 1 ≤ a i , b i ≤ 1 0 4 1 \leq a_i, b_i \leq 10^4 1ai,bi104

思路

在这个问题中,有一个背包,其容量是时间t,还有m种不同的草药,每种草药都有自己的采集时间a[i]和价值b[i]。目标是在不超过背包容量的情况下,最大化背包中草药的总价值。

可以将每种草药视为一种物品,其“重量”是采集时间,其“价值”是草药的价值。这个问题的特点是,每种草药可以无限次采集,只要时间允许。这就是所谓的“完全背包”问题。

定义状态dp[j]为当背包容量为j时,能够获得的最大价值。初始化状态时,假设背包为空,所以所有的dp[j]都为0。

然后开始填充状态表。对于每种草药i,都会尝试将其添加到背包中,看看是否能提高背包的总价值。具体来说,对于每个可能的背包容量j,如果可以将草药i添加到背包中(即j >= a[i]),那么就有两种选择:一是不添加草药i,此时背包的总价值仍然是dp[j];二是添加草药i,此时背包的总价值变为dp[j - a[i]] + b[i]。目标是使背包的总价值最大,所以选择两者中的较大值作为新的dp[j]

这是完全背包问题,而不是01背包问题。在完全背包问题中,每种物品可以被选择多次,因此在考虑是否选择当前物品时,需要查看在选择该物品多次的情况下能够获得的最大价值。

在这个问题中,for (int j = a[i]; j <= t; j++) 的作用是遍历所有可能选择当前物品的情况。由于可以选择当前物品多次,因此需要从小到大遍历 j。这样,当考虑到 j 时,dp[j - a[i]] 对应的是已经选择了当前物品的情况,因此 dp[j] 可以通过选择当前物品来更新。

如果从大到小遍历 j,即 for (int j = t; j >= a[i] j--),那么当考虑到 j 时,dp[j - a[i]] 对应的是还没有选择当前物品的情况,因此 dp[j] 只能通过不选择当前物品来更新。这就变成了01背包问题,每种物品只能被选择一次。

最后输出dp[t],这就是当背包容量为t时,能够获得的最大价值,也就是答案。


AC代码

#include <algorithm>
#include <iostream>
#define AUTHOR "HEX9CF"
#define ll long long
using namespace std;const int N = 1e7 + 7;int t, m;
// 时间,价值
int a[N], b[N];
ll dp[N];int main() {cin >> t >> m;for (int i = 1; i <= m; i++) {cin >> a[i] >> b[i];}for (int i = 1; i <= m; i++) {for (int j = a[i]; j <= t; j++) {dp[j] = max(dp[j], dp[j - a[i]] + b[i]);}}cout << dp[t] << endl;return 0;
}
http://www.lryc.cn/news/296100.html

相关文章:

  • L1-027 出租分数 20
  • 51单片机精进之路-1点亮led灯
  • 嵌入式学习Day14 C语言 --- 位运算
  • idea设置terminal为git
  • 《MySQL 简易速速上手小册》第3章:性能优化策略(2024 最新版)
  • 【golang】23、gorilla websocket 源码:examples、数据结构、流程
  • SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式 基础(持续更新~)
  • flask+pyinstaller实现mock接口,并打包到exe运行使用postman验证
  • 【Spring Boot】第一篇 创建简单的Spring Boot项目
  • SSL协议是什么?关于SSL和TLS的常见问题解答
  • 第十五个知识:JQuery
  • 用Matlab 2015a svmtrain函数训练的SVM model在2021b无法使用的解决方法
  • umount:/home/tuners/windows files:目标忙。
  • FPGA_vga显示
  • sklearn模型指标和特征贡献度查看
  • 2024.2.6日总结(小程序开发3)
  • 相机图像质量研究(10)常见问题总结:光学结构对成像的影响--光圈
  • TCP和UDP相关问题(重点)(3)——3.HTTP基于TCP还是UDP?
  • 基于modbus rtu协议操作PLC的EPICS示例
  • 网站被攻击有什么办法呢?
  • VoIP之主备注册服务器机制
  • 【数据分享】1929-2023年全球站点的逐年平均降水量(Shp\Excel\免费获取)
  • uniapp /微信小程序 使用map组件实现手绘地图方案
  • react+antd+CheckableTag实现Tag标签单选或多选功能
  • UUID和雪花(Snowflake)算法该如何选择?
  • Jetpack Compose之进度条介绍(ProgressIndicator)
  • 【Qt基本功修炼】Qt线程的两种运行模式
  • 三、设计模式相关理论总结
  • 鸿蒙 WiFi 连接 流程
  • golang 创建unix socket http服务端