详解信奥一本通1290:采药

news2025/1/13 2:46:15

1290:采药

【题目描述】

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

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

【输入】

输入的第一行有两个整数T(1<=T<=1000)和M(1<=M<=100),T代表总共能够用来采药的时间,M代表山洞里的草药的数目。接下来的M行每行包括两个在1到100之间(包括1和100)的的整数,分别表示采摘某株草药的时间和这株草药的价值。

【输出】

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

【输入样例】

70 3

71 100

69 1

1 2

【输出样例】

3


思路

基础的动态规划

线性动态规划

  1. 抽象的(背包)

  1. 直观的(给你个数轴从1到n,给你个矩阵从1,1到n,n)

01背包

给出 n 个草药,第 i 个草药需要花费 $w_i$ 的时间,这个草药的价格为 $v_i$

时间最多为 $T$,问最多能拿到多少价值的草药

int dp[110][1100];
// 表示当前判断第 now 个草药,前面已选的草药总时间为 sum_v, 已选草药总价值为 sum_v
void dfs(int now, int sum_w, int sum_v){
	// 2.出口
	if (now > n){
		ans = max(ans, sum_v);
		return;	
	}
	// 之前到达 now sum_w 的草药最大价值如果大于等于现在的 sum_v
	if (dp[now][sum_w] >= sum_v){
		// 那就没有必要继续搜索了,因为之前搜过的更好
		return;
	}
	// 否则当前这一次搜索更好,那就记录最大值
	dp[now][sum_w] = sum_v;
	
	// 1.能做的事情
	if (sum_w + w[now] <= T){
		dfs(now + 1, sum_w + w[now], sum_v + v[now]);	
	}
	dfs(now + 1, sum_w, sum_v);
}
int main(){
	...
	memset(dp, -1, sizeof(dp));
	dfs(1, 0, 0);
	return 0;	
}

动态规划四要素

  1. 状态

状态怎么去找?

题目/搜索

三个状态数据使用二维数组

$dp[now][sumw] = sumv$

把题目中随着操作会发生变化的数据全部列出来

A. 时间 B. 草药 C.价值

$dp[now][sumw] = sumv$

// dp[now][sumw] 表示前 now 个草药,消耗时间为 $sumw$ 的最大价值

列出状态数组后,请记得写一句注释

  1. 状态转移方程

考虑当前能做什么事情,每个操作分别会从哪个状态变化到哪个状态

// 拿第 now 个草药之后会变成什么样
if (sum_w + w[now] <= T){
	当前状态是      dp[now][sumw]
	拿了之后会变化到 dp[now + 1][sum_w + w[now]
	操作的效果是 + v[now]
	得到方程 dp[now + 1][sum_w + w[now]] = dp[now][sumw] + v[now];
}
// 不拿第 now 个草药之后会变成什么样
当前状态是      dp[now][sumw]
不拿会变化到    dp[now + 1][sum_w]
操作的效果是    没有效果
得到方程 dp[now + 1][sum_w] = dp[now][sumw]

状态转移方程最常见的两种写法(转移方向):1. 到哪去 2. 从哪来

就是思考 $dp[now][sumw]$ 能从哪些状态转移过来

// 拿第 now 个草药之后变成了 dp[now][sumw]
拿之前是      dp[now-1][sumw - w[now]]
拿完之后变成了 dp[now][sumw]
操作的效果  + v[now]
得到方程 dp[now][sumw] = dp[now - 1][sumw - w[now]] + v[now];
// 不拿第 now 个草药之后变成了 dp[now][sumw]
不拿之前是     dp[now-1][sumw]  
拿完之后变成了 dp[now][sumw]
操作的效果    没有效果
得到方程 dp[now][sumw] = dp[now - 1][sumw];
  1. 初始化

就是思考数组一开始要怎么样

一开始没有拿过任何草药,所以所有的价值都为 0

  1. 答案

  1. 转移顺序

当我们使用 $dp[now][sumw]$ 时,要保证 $dp[now][sumw]$ 已经是最优解

状态的定义:dp[now][sumw] 表示前 now 个草药花费时间正好是 sumw 的最大价值
状态转移方程:dp[now][sumw] = max(dp[now - 1][sumw], dp[now - 1][sumw - w[now]]);要保证状态存在才能转移
初始化:dp[0][0] = 0 一开始没有草药,没有花时间,价值为 0
答案: dp[n][t]
#include <bits/stdc++.h>
using namespace std;
int w[10000], v[10000];
int dp[110][1100];
int main() {
	int t, n;
	cin >> t >> n;
	for (int i = 1; i <= n; ++i){
		cin >> w[i] >> v[i];
	}
	memset(dp, -1, sizeof(dp));
	dp[0][0] = 0;
	for (int now = 1; now <= n; ++now){
		for (int sumw = 0; sumw <= t; ++ sumw){
			if (dp[now - 1][sumw] != -1){
				dp[now][sumw] = dp[now - 1][sumw];
			}
			if (sumw - w[now] >= 0 && dp[now - 1][sumw - w[now]] != -1){
				 dp[now][sumw] = max(dp[now][sumw], dp[now - 1][sumw - w[now]] + v[now]);
			}	
		}
	}
	int ans = 0;
	for (int i = 0; i <= t; ++i){
		ans = max(ans, dp[n][i]);
	}
	cout << dp[n][t] << endl;
	return 0;
}
状态的定义:dp[now][sumw] 表示前 now 个草药花费时间不超过 sumw 的最大价值
状态转移方程:dp[now][sumw] = max(dp[now - 1][sumw], dp[now - 1][sumw - w[now]]);
初始化:全部为0,一开始假设所有时间都可以被浪费掉,花费任意的时间均没有收入
答案: dp[n][t]

#include <bits/stdc++.h>
using namespace std;
int w[10000], v[10000];
int dp[110][1100];
int main() {
	int t, n;
	cin >> t >> n;
	for (int i = 1; i <= n; ++i){
		cin >> w[i] >> v[i];
	}
	for (int now = 1; now <= n; ++now){
		for (int sumw = 0; sumw <= t; ++ sumw){
			dp[now][sumw] = dp[now - 1][sumw];
			if (sumw - w[now] >= 0){
				 dp[now][sumw] = max(dp[now][sumw], dp[now - 1][sumw - w[now]] + v[now]);
			}	
		}
	}
	cout << dp[n][t] << endl;
	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/179029.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Fisco Bcos区块链三(webase中间件平台一键部署)

文章目录区块链开荒技术文档&#xff1a;https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/index.html4. Webase一键部署Java环境变量配置MySQL安装Ubuntu安装mysql数据库安装后设置密码&#xff1a;Python部署PyMySQL部署&#xff08;Python3.6&#xff09;拉取…

SpringBoot-过滤器的使用(在访问页面时过滤掉未登录的用户使其不能访问相应页面)

目录 概述 前端编写 页面展示 后端编写 编写接口 过滤器的编写 过滤器功能实验 概述 解决需求&#xff1a;在用户未登录的情况下访问未登录不可访问的页面时&#xff0c;请求将被过滤到&#xff0c;将用户退回登录页面。 技术选型 前端&#xff1a;Vue ElementUI 后端…

MySQL事务的四大特性以及并发事务问题

事务的四大特性ACID 【原子性&#xff08;Atomicity&#xff09;】&#xff1a;事务是不可分割的最小单元&#xff0c;要么全部成功&#xff0c;要么全部失败。&#xff08;eg&#xff1a;转账案例&#xff0c;转账过程中任何一步操作失败了&#xff0c;那么整个事务就失败了&a…

Python装饰器使用方法详解

文章目录1 装饰器背景知识1.1 基本概念1.2 应用场景2 简单的装饰器代码3 使用装饰器记录函数执行次数4 带参数的装饰器5 装饰器处理有返回值的函数1 装饰器背景知识 1.1 基本概念 装饰器&#xff08;Decorator&#xff09;是 Python 中一种函数或类&#xff0c;用来修饰其他函…

RabbitMQ部署

RabbitMQ部署1.单机部署1.1.下载镜像1.2.安装MQ1.3访问管理端2.集群部署2.1.集群分类2.2.设置网络1.单机部署 我们在Centos7虚拟机中使用Docker来安装&#xff0c;如未安装dockr&#xff0c;请参考《Centos7安装Docker》 1.1.下载镜像 方式一&#xff1a;在线拉取 docker …

C语言linux线程库pthread的简单使用教程

POSIX线程&#xff08;pthread&#xff09;库 POSIX线程库是用于C/C的基于标准的线程API。它允许产生一个新的并发流程。它在多处理器或多核系统上最为有效&#xff0c;在这些系统中&#xff0c;可以将流程安排在另一个处理器上运行&#xff0c;从而通过并行或分布式处理提高速…

flask框架全解

文章目录简介wsgiref安装配置文件方式一&#xff08;debug方式配置&#xff09;方式二&#xff08;环境变量方式&#xff0c;很少见&#xff09;方式三&#xff08;配置文件方式&#xff09;其他配置方式flask app路由组成写法动态路由的过滤查询字符串传参json和form等数据反向…

deepin系统如何安装惠普打印机

deepin系统如何安装惠普打印机 导读 想必现在有很多小伙伴对于deepin系统如何安装惠普打印机 安装惠普打印机的方法方面的知识都比较想要了解&#xff0c;那么今天小好小编就为大家… 想必现在有很多小伙伴对于deepin系统如何安装惠普p1007打印机 安装惠普打印机的方法方面的知…

【图卷积神经网络】02-谱域图卷积介绍

注&#xff1a;本文为第2章谱域图卷积介绍视频笔记&#xff0c;仅供个人学习使用 目录1、图卷积简介1.1 图卷积网络的迅猛发展1.2 回顾&#xff0c;经典卷积神经网络已在多个领域取得成功1.3 两大类数据1.4 经典卷积神经网络的局限&#xff1a;无法处理图数据结构1.5 将卷积扩展…

Python学习基础之快速入门

目录 首先我们下载最新的python版本&#xff1a;3.0 编写一个hello world 什么是python里面的IPO python运行有几种模式 编写一个温度转换器 在windows上执行python程序 官网&#xff1a;Welcome to Python.org Python 是一门易于学习、功能强大的编程语言。它提供了高效的…

保护视力台灯是白光还是暖光?盘点专业护眼的暖光护眼台灯

保护视力的灯光颜色是最接近太阳光最好&#xff0c;而白光与暖光主要是色温来控制的&#xff0c;低色温&#xff08;3000K以下&#xff09;&#xff0c;中性色温&#xff08;4000K左右&#xff09;&#xff0c;高色温&#xff08;5000K以上&#xff09;&#xff0c;低色温的光源…

在不受支持的 Mac 上安装 macOS Ventura、Monterey、Big Sur (OpenCore Legacy Patcher)

在不受支持的 Mac 上安装 macOS Ventura、Monterey、Big Sur (OpenCore Legacy Patcher) 请访问原文链接&#xff1a;https://sysin.org/blog/install-macos-13-on-unsupported-mac/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;www.s…

RabbitMQ入门与应用

RabbitMQ入门与应用1.初识MQ1.1.同步和异步通讯1.1.1.同步通讯1.1.2.异步通讯1.2.技术对比&#xff1a;2.快速入门2.1.安装RabbitMQ2.2.RabbitMQ消息模型2.3.导入Demo工程2.4.入门案例2.4.1.publisher实现2.4.2.consumer实现2.5.总结3.SpringAMQP3.1.Basic Queue 简单队列模型3…

python机器学习数据建模与分析——pandas中常用函数总结

本文主要对数据建模与分析中常使用到的pandas内置函数进行总结分析&#xff0c;以此来熟悉数据建模与分析的流程。 文章目录一、Pandas数据结构1.1 数据结构—Series1.1.1 Series的创建方式1.1.2 使用索引和获取数据1.2 数据结构—DataFrame1.2.1 DataFrame的创建方式1.2.2 使用…

变速积分PID算法及仿真

在普通的PID 控制算法中&#xff0c;由于积分系数k是常数&#xff0c;所以在整个控制过程中&#xff0c;积分增量不变。而系统对积分项的要求是&#xff0c;系统偏差大时积分作用应减弱甚至全无&#xff0c;而在偏差小时则应加强。积分系数取大了会产生超调&#xff0c;甚至积分…

强化学习笔记:基于价值的学习之价值迭代(python实现)

目录 1. 前言 2. 数学原理 3. 实现 3.1 Planner类 3.2 ValueIterationPlanner类 4. 运行结果及分析 1. 前言 在强化学习中&#xff0c;根据是否依赖于&#xff08;环境的&#xff09;模型&#xff0c;可以分为有模型&#xff08;model-based&#xff09;…

通信原理简明教程 | 模拟调制传输

文章目录1 模拟幅度调制1.1 模拟幅度调制的基本原理1.2 DSB-SC调制和AM调制1.3 SSB调制和VSB调制2 模拟角度调制2.1 角度调制的基本概念2.2 窄带调频和宽带调频2.3 调频信号的产生方法3 模拟调制系统的解调3.1 相干解调3.2 非相干解调4 模拟调制系统的抗噪声性能4.1 抗噪声性能…

Service Mesh

Service Mesh 参考如下文章&#xff1a;可以将此文章看作为下面文章的结合&#xff1a; https://zhuanlan.zhihu.com/p/61901608 https://philcalcado.com/2017/08/03/pattern_service_mesh.html https://zhuanlan.zhihu.com/p/153105848?from_voters_pagetrue 微服务演化进…

浅谈 开源许可证

目录浅谈 开源许可证一、什么是开源许可证1.1 什么是开源1.2 什么是开源许可证Copyleft 许可证&#xff08;Copyleft 许可证&#xff09;宽松许可证&#xff08;permissive 许可证&#xff09;二、为什么要有开源许可证2.1、No License&#xff1a;没有开源许可证意味着什么2.2…

38.Isaac教程--AprilTags

AprilTags ISAAC教程合集地址文章目录AprilTags源码Isaac Codelet运行示例应用程序在主机系统上运行示例应用程序在 Jetson 上运行应用程序在 Websight 中查看应用程序的输出AprilTags 是一种流行的基准标记形式。 它在机器人技术中有广泛的应用&#xff0c;包括对象跟踪、视觉…