首页 > 其他分享 >[刷题笔记] Luogu P1877 音量调节

[刷题笔记] Luogu P1877 音量调节

时间:2023-08-01 20:58:49浏览次数:42  
标签:P1877 背包 level int Luogu 01 音量 操作 刷题

Problem

Description

共\(n\)次操作,每次操作有一个值\(a_i\),同时给定一个初始值\(start\),对于每次操作,可以将值\(k\)加或减\(a_i\)(\(k\)初始=\(start\)),求经过这\(n\)操作后\(k\)的最大值。


Solution

其实这是一个01背包的变形。

这和01背包有何关系呢?
回顾一下经典01背包:有若干件物品,每个物品有重量和价值两个参数,有一个背包,背包容量有限,求背包在不超过容量的前提下价值最大。

那本题呢?

有若干次操作,每次操作可以选择加或减,求最大值?

我们可以反向思考,用\(f\)数组存储该音量是否可以达到,最后统计答案从MAX_LEVEL倒着搜是不是就可以解决了?!

设计状态:\(f_{i,j}\)表示前\(i\)次操作音量\(j\)是否可达。

考虑转移:音量\(j\)可以通过\(j+a_i\)或者\(j-a_i\)得到(\(a_i\)为每次操作的参数)。由于我们一次转移是依据上一次操作的,故枚举时应当先枚举操作次数,再转移。
这样我们就能确保每次转移都能依据上一次操作,同时满足无后效性。

还是非常可爱的题呢QAQ!


Code

/* 01背包变形
朴素01背包需求一件物品选or不选的max,而本题求经过n次操作后的max
我们可以求每个音量是否可以得到!
还是两个状态,f[i][j]表示经过i次操作后的音量j是否可得。
容易发现可以递推得到
最后倒着从max_level搜如果可以实现直接输出即可。 
*/

#include <iostream>
#include <cstdio>
#include <algorithm>
#define N 1010
using namespace std;
int n,begin_level,max_level; 
int f[N][N];
int c[N];
int main()
{
	scanf("%d%d%d",&n,&begin_level,&max_level);
	for(int i=1;i<=n;i++) scanf("%d",&c[i]);
	f[0][begin_level] = 1;
	for(int i=1;i<=n;i++)
	{
		for(int j=0;j<=max_level;j++)
		{
			int x = j+c[i],y = j-c[i];
			if(y>=0&&f[i-1][y]) f[i][j] = 1;
			if(x <= max_level && f[i-1][x]) f[i][j] = 1;
		}
	}
	for(int i=max_level;i>=0;i--)
	{
		if(f[n][i])
		{
			cout<<i<<endl;
			return 0;
		}
	}
	cout<<"-1"<<endl;
	return 0;
}

标签:P1877,背包,level,int,Luogu,01,音量,操作,刷题
From: https://www.cnblogs.com/SXqwq/p/17599048.html

相关文章

  • 【题解】Luogu[P2420] 让我们异或吧
    Link看到是树,又多组询问,立马想到类似的求和问题,异或不好理解,我们想求和怎么做,维护\(dis_i\)表示\(i\)节点到根的权值和,那么对于\(u,v\)两点路径上的权值和就是\(dis_u+dis_v-2\timesdis_{\mathrm{lca}(u,v)}\),这是很经典的问题了。事实上刚才的求和我们可以转化一下,我们......
  • 链表双指针技巧汇总 [labuladong-刷题打卡 day1]
    双指针合并21.合并两个有序链表比较简单的双指针比较算法,两个指针分别指向待合并链表/序列,比较后选择符合条件的指针移动Trick:链表在实现时,带头节点的链表在操作中更方便题解/***Definitionforsingly-linkedlist.*structListNode{*intval;*ListNo......
  • [并查集] 题单刷题摘要
    题单1.P6121[USACO16OPEN]ClosingtheFarmGP3144[USACO16OPEN]ClosingtheFarmS(逊版)思路\(\scr{Solution}\)每一时刻关闭农场,求是否全联通。也就是维护将单个集合分成多个集合。很容易想到爆搜算法,用vector邻接表建图,每次跑完图就将当前点的连边关系删去。复杂度......
  • 暑假刷题记 B
    动态规划字符串杂题A:AnimalsandPuzzleB:VanyaandTreasure根号分治。实际上是从\((1,1)\)先找一个\(1\),再找一个\(2\dots\)最后找一个\(p\)然后依次按最短路走过去。我们有两种想法,直接BFS递推得到当前点到所有点的距离或者直接暴力枚举两个层之间的所有......
  • 暑假刷题记 A
    数据结构Ice-creamTycoon平衡树/线段树二分。对于平衡树而言,构造一个函数,求出拿到最便宜的所需数量的ice-cream的价格(利用类似于树上查排名的操作即可),比较该价格与所有钱数的差别即可。对于线段树二分而言,利用数量的单调性,求出对应的节点,然后修改该节点前的所有......
  • luogu P4069 [SDOI2016] 游戏 题解【李超树+树剖】
    目录题目描述解题思路code题目描述P4069[SDOI2016]游戏一棵树,树上有\(n\)个节点,最初每个节点上有\(1\)个数字:\(123456789123456789\)。有两种操作:\(\centerdot\)选择\(s,t\)两个节点,将路径上的每一个点都变多(\(1\)个变\(2\)个)数字:\(a\timesdis+b\),其中\(dis\)表示该节点......
  • luogu P3733 [HAOI2017] 八纵八横 题解【线段树分治+线性基+可撤销并查集+bitset】
    目录题目大意解题思路code题目大意题目链接给出一张\(n\)个点\(m\)条边的连通无向图,边带边权\(w_i\)。有以下三种操作,共\(q\)次:\(\centerdot\)在点\(x,y\)之间加入一条边权为\(w_i\)的边,如果这是第\(i\)个此种操作,则记这条新边为第\(i\)条。\(\centerdot\)将第\(k......
  • 【题解】Luogu[P4711] 「化学」相对分子质量
    Link一道简单的模拟题,评绿可能有点高了。因为没有括号嵌套,难度瞬间降了一个档次,我们直接对着化学式扫一遍即可。若扫到左括号,说明接下来都是在括号内的,我们标记一下。若扫到大写字母,说明出现了一个新的元素,那么我们就看后面是否有下标,若有则类似于快读的方式直接处理后面的数......
  • luogu P9474 [yLOI2022] 长安幻世绘 详细题解
    原题:P9474[yLOI2022]长安幻世绘看到很多大佬的题解直接讲了做法,本蒟蒻看得不是很懂,调了很久才把这题做出来,于是写了这篇比较详细的题解谈一下我做这题从头到尾的思路,希望对各位有帮助qwq。思路我们首先思考这样一个问题,如果已经知道最终答案对应的最大值和最小值,又不知道题......
  • 算法刷题笔记--并查集的运用
    1、题目描述:一个城市中有两个犯罪团伙A和B,你需要帮助警察判断任意两起案件是否是同一个犯罪团伙所为,警察所获得的信息是有限的。假设现在有N起案件(N<=100000),编号为1到N,每起案件由团伙A或团伙B所为。你将按时间顺序获得M条信息(M<=100000),这些信息分为两类:D[a][b]其中[a]和[b]表示两......