【题解】洛谷P1759 通天之潜水

news/2024/6/15 21:41:01 标签: 算法, 动态规划

通天之潜水

题目背景

直达通天路·小 A 历险记第三篇

题目描述

在猴王的帮助下,小 A 终于走出了这篇荒山,却发现一条波涛汹涌的河拦在了自己的面前。河面上并没有船,但好在小 A 有 n n n 个潜水工具。由于他还要背重重的背包,所以他只能背 m m m 重的工具,又因为他的力气并不是无限的,河却很宽,所以他只能背有 v v v 阻力的工具。但是这条河下有非常重要的数据,所以他希望能够停留的时间最久。于是他找到了你,让你告诉他方案。

输入格式

三个数 m , v , n m, v, n m,v,n 如题目所说。

接下来 n n n 行,每行三个数 a i , b i , c i a_i, b_i, c_i ai,bi,ci 分别表示所含的重力,阻力,能够支撑的时间。

输出格式

第一行一个数,表示最长的时间。

接下来一行,若干个数,表示所选的物品。

样例 #1

样例输入 #1

100 100 3
50 60 289
40 10 116
50 50 106

样例输出 #1

405 
1 2

提示

对于 100 % 100 \% 100% 的数据, 1 ≤ m , v ≤ 200 1 \le m, v \le 200 1m,v200 1 ≤ n ≤ 100 1 \le n \le 100 1n100

数据保证一定有方案。

若有多种方案,输出前面尽量小的方案。


看起来是个很简单的二维费用背包是吧,只要模仿01背包的做法就可以了。
这个题为什么是绿色的?还需要输出选择物品的方案,而且题目会卡,不优化空间就会MLE,因此我们需要在滚动数组/二维数组(二位费用背包本来是三维的)的情况下,输出选择物品的方案。

为了循序渐进,先考虑三维状态的背包是如何输出选择物品的方案的,每个状态[物品数][费用1][费用2]存一个vector,加上这个vector,这个数组是四维数组了,当然网上看到有用char存的,如果不用vector改用char或许不需要优化空间直接就过了。我们需要在每次发现可以更新的时候,把子问题的物品选择方案复制一份过来,然后把当前物品的编号放进后面去。

注意:每个状态只更新了一次,因为循环只会在这个状态停留一次,那么在更新/沿用i-1的时候,只会这样被处理一次物品选择的方案,不会反复修改。换句话说,每个状态的物品选择方案,一旦更新就肯定是**使得价值最大(但是对于同样的最大价值,方案可能不唯一,首次选择用哪种方案,并不确定,需要修改代码细节来控制,详见下文)**的方案。

既然每个状态只更新一次,那么选择的“路径”是无后效性的,可以边递推边存储路径。

但是这个题真的值绿色吗? 毫无疑问我这样做hack都没过, 注意到,题目的最后,写明了要输出的方案要求前面的物品尽可能编号小,用hack1的数据试一下你就懂了

先上我的没AC的代码:

#include<iostream>
#include<vector>
using namespace std;
int m,v,n,a[101],b[101],c[101];
int f[201][201];
vector<int> items[201][201];
int main()
{
	cin>>m>>v>>n;
	for(int i=1;i<=n;i++)
	cin>>a[i]>>b[i]>>c[i];
	for(int i=1;i<=n;i++)
	{
		for(int j=m;j>=a[i];j--)
		{
			for(int k=v;k>=b[i];k--)
			{
				if(f[j-a[i]][k-b[i]]+c[i]>f[j][k])
				{
					f[j][k]=f[j-a[i]][k-b[i]]+c[i];
					items[j][k]=items[j-a[i]][k-b[i]];
					items[j][k].push_back(i);
				}
				else items[j][k]=items[j][k];
			}
		}
	}
	cout<<f[m][v]<<endl;
	for(int i=0;i<items[m][v].size();i++)
	{
		cout<<items[m][v][i]<<" ";
	}
	return 0;
}

分析可知我的代码的更新条件是“惰性”的,必须要严格增才会更新,也就是说,我的代码会使得最后一个物品的编号尽可能小
如果加了等于号,那么会使得最后一个物品的编号尽可能大

敏锐的你一定会察觉到,只要把物品的顺序反过来,那么就变成了第一个物品的编号尽可能小,最后再反序输出就得到正确顺序的答案了

AC代码如下:

#include<iostream>
#include<vector>
using namespace std;
int m,v,n,a[101],b[101],c[101];
int f[201][201];
vector<int> items[201][201];
int main()
{
	cin>>m>>v>>n;
	for(int i=1;i<=n;i++)
	cin>>a[i]>>b[i]>>c[i];
	for(int i=n;i>=1;i--)
	{
		for(int j=m;j>=a[i];j--)
		{
			for(int k=v;k>=b[i];k--)
			{
				if(f[j-a[i]][k-b[i]]+c[i]>=f[j][k])
				{
					f[j][k]=f[j-a[i]][k-b[i]]+c[i];
					items[j][k]=items[j-a[i]][k-b[i]];
					items[j][k].push_back(i);
				}
				else items[j][k]=items[j][k];
			}
		}
	}
	cout<<f[m][v]<<endl;
	for(int i=items[m][v].size()-1;i>=0;i--)
	{
		cout<<items[m][v][i]<<" ";
	}
	return 0;
}

http://www.niftyadmin.cn/n/5476542.html

相关文章

最佳情侣身高差

题目描述 专家通过多组情侣研究数据发现&#xff0c;最佳的情侣身高差遵循着一个公式&#xff1a;&#xff08;女方的身高&#xff09;1.09 &#xff08;男方的身高&#xff09;。如果符合&#xff0c;你俩的身高差不管是牵手、拥抱、接吻&#xff0c;都是最和谐的差度。 下面…

备忘,LangChain建立本地知识库的几个要点

本地知识库可以解决本地资源与AI结合的问题&#xff0c;为下一步应用管理已有资产奠定基础。 本地知识库的建立可参考LangChain结合通义千问的自建知识库 &#xff08;二&#xff09;、&#xff08;三&#xff09;、&#xff08;四&#xff09; 本文主要记录两个方面的问题 1 搭…

OpenCV 4.9基本绘图

返回&#xff1a;OpenCV系列文章目录&#xff08;持续更新中......&#xff09; 上一篇&#xff1a;OpenCV使用通用内部函数对代码进行矢量化 下一篇:使用OpenCV4.9的随机生成器和文本 ​目标 在本教程中&#xff0c;您将学习如何&#xff1a; 使用 OpenCV 函数 line() 画一…

vue watch监听的多种使用

简述&#xff1a;vue 的watch的监听使用的几种写法。常用第4中写法。 一、$route监听路由跳转 前提&#xff1a;当需要前端监听路由跳转的时候&#xff0c;一般写在App.vue入口 //App.vue //vue2、uniapp写法 watch: {$route(to, from) {if (hasPermission(to.path)) {this…

SpringBoot及其特性

0.前言 Spring 框架提供了很多现成的功能。那么什么是 Spring Boot&#xff1f;使用 Spring 框架&#xff0c;我们可以避免编写基础框架并快速开发应用程序。为了让 Spring 框架提供基础框架&#xff0c;我们需要向 Spring 框架描述有关我们的应用程序及其组件的信息。 不只是…

JavaScript之作用域链详解

在JavaScript中&#xff0c;作用域链是一个重要的概念&#xff0c;它决定了变量和函数的可访问性。作用域链是由变量对象的列表组成&#xff0c;这些变量对象按照它们被创建的顺序排列。本文将详细介绍JavaScript作用域链&#xff0c;包括什么是作用域链、作用域链的创建过程、…

文旅元宇宙|“元宇宙+”全面赋能智慧文旅场景建设

元宇宙作为下一代互联网入口&#xff0c;正在潜移默化的改变着人生的生活方式&#xff0c;不断催生新业态&#xff0c;带给人们前所未有的体验。元宇宙概念的崛起&#xff0c;正以其独特的魅力&#xff0c;引领着一场全新的智慧文旅革命。元宇宙&#xff0c;这个融合了虚拟现实…

LinkedHashMap 集合源码分析

LinkedHashMap 集合源码分析 文章目录 LinkedHashMap 集合源码分析一、字段分析二、内部类分析三、构造方法分析四、内部方法分析五、总结 LinkedHashMap 是 HashMap 的子类&#xff0c;在 HashMap 的基础上维护了双向链表&#xff0c;保证了有序性。默认是不排序的&#xff0c…