CF1561C Deep Down Below 题解

文章提供了一个关于游戏策略的问题,玩家控制的英雄需要击败具有不同装甲值的怪物。每个任务包含一定数量的怪物,玩家必须按照顺序战斗。文章讨论了不同的算法思路,包括TLE(超时)的初始朴素算法和AC(Accepted)解决方案,后者通过两阶段处理优化了时间复杂度,达到通过所有测试用例的效率。
摘要由CSDN通过智能技术生成

题目

链接

https://www.luogu.com.cn/problem/CF1561C

字面描述

Deep Down Below

题面翻译

T T T 组数据,每次给定 n n n 个任务,第 i i i 个任务给定 k i k_i ki 个怪物,每个怪物有一个能力值 a i , j a_{i,j} ai,j 你要按顺序把这 k i k_i ki 个怪物杀死,你能杀死一个怪物当且仅当你的能力值严格大于怪物的能力值,杀死一个怪物后,你的能力值将会 + 1 +1 +1

你可以按任意顺序完成这 n n n 个任务,你需要确定最小的初始能力值。

T ≤ 1 0 5 , n ≤ 1 0 5 , k i ≤ 1 0 5 , ∑ k i ≤ 1 0 5 , a i , j ≤ 1 0 9 T\leq 10^5,n\leq 10^5,k_i\leq10^5,\sum k_i\leq 10^5,a_{i,j}\leq 10^9 T105,n105,ki105,ki105,ai,j109

题目描述

In a certain video game, the player controls a hero characterized by a single integer value: power. The hero will have to beat monsters that are also characterized by a single integer value: armor.

On the current level, the hero is facing $ n $ caves. To pass the level, the hero must enter all the caves in some order, each cave exactly once, and exit every cave safe and sound. When the hero enters cave $ i $ , he will have to fight $ k_i $ monsters in a row: first a monster with armor $ a_{i, 1} $ , then a monster with armor $ a_{i, 2} $ and so on, finally, a monster with armor $ a_{i, k_i} $ .

The hero can beat a monster if and only if the hero’s power is strictly greater than the monster’s armor. If the hero can’t beat the monster he’s fighting, the game ends and the player loses. Note that once the hero enters a cave, he can’t exit it before he fights all the monsters in it, strictly in the given order.

Each time the hero beats a monster, the hero’s power increases by $ 1 $ .

Find the smallest possible power the hero must start the level with to be able to enter all the caves in some order and beat all the monsters.

输入格式

Each test contains multiple test cases. The first line contains the number of test cases $ t $ ( $ 1 \le t \le 10^5 $ ). Description of the test cases follows.

The first line of each test case contains a single integer $ n $ ( $ 1 \le n \le 10^5 $ ) — the number of caves.

The $ i $ -th of the next $ n $ lines contains an integer $ k_i $ ( $ 1 \le k_i \le 10^5 $ ) — the number of monsters in the $ i $ -th cave, followed by $ k_i $ integers $ a_{i, 1}, a_{i, 2}, \ldots, a_{i, k_i} $ ( $ 1 \le a_{i, j} \le 10^9 $ ) — armor levels of the monsters in cave $ i $ in order the hero has to fight them.

It is guaranteed that the sum of $ k_i $ over all test cases does not exceed $ 10^5 $ .

输出格式

For each test case print a single integer — the smallest possible power the hero must start the level with to be able to enter all the caves in some order and beat all the monsters.

样例 #1

样例输入 #1

2
1
1 42
2
3 10 15 8
2 12 11

样例输出 #1

43
13

提示

In the first test case, the hero has to beat a single monster with armor $ 42 $ , it’s enough to have power $ 43 $ to achieve that.

In the second test case, the hero can pass the level with initial power $ 13 $ as follows:

  • enter cave $ 2 $ :
    • beat a monster with armor $ 12 $ , power increases to $ 14 $ ;
    • beat a monster with armor $ 11 $ , power increases to $ 15 $ ;
  • enter cave $ 1 $ :
    • beat a monster with armor $ 10 $ , power increases to $ 16 $ ;
    • beat a monster with armor $ 15 $ , power increases to $ 17 $ ;
    • beat a monster with armor $ 8 $ , power increases to $ 18 $ .

思路

TLE算法

具体思想

本人最初的想法十分的朴素,针对 n n n个任务维护 n n n个队首指针。

  • 每次比较出 n n n个任务队首怪兽的最小值
  • 与当前预算的能力值比较是否能继续打怪,是 -> 继续 ,否 -> 加到怪兽能力值+1即可。

TLE特例

如果有1e5个任务,每个任务只有1个怪兽。
按此算法:

时间复杂度退化: O ( n ⋅ Σ k ) ≈ 1 e 10 O(n·Σk)≈1e10 O(nΣk)1e10 TLE ! ! !

AC思想

2阶段处理

  1. 算出每组打怪加能力的情况下每一个怪兽所对应初始能力值,并取max
  2. n n n个max从小到大排序,依次循环,看每个max加上对应任务里的元素数(能加多少次能力),是否能满足下一个max,是 -> continue ,否 -> 加到下一个max。

时间复杂度: O ( Σ k ⋅ l o g ( Σ k ) ) ≈ 2 e 6 O(Σk·log(Σk))≈2e6 O(Σklog(Σk))2e6

阶段线性处理,tql !

代码实现

#include<bits/stdc++.h>
using namespace std;

const int maxn=1e5+10;
int t,n,ans;
int k[maxn];
vector<int>e[maxn];
struct node{
	int v,cnt;
}a[maxn];
inline bool cmp(node p,node q){return p.v<q.v;}
int main(){
	scanf("%d",&t);
	while(t--){
		scanf("%d",&n);
		for(int i=1;i<=n;i++){
			e[i].clear();
			scanf("%d",&k[i]);
			//算每组的最大值
			for(int j=1;j<=k[i];j++){
				int x;
				scanf("%d",&x);
				x=x+2-j;
				if(j!=1)x=max(x,e[i][j-2]);
				e[i].push_back(x);
			}
			a[i].v=e[i][k[i]-1];//最大值的最小取值
			a[i].cnt=k[i];//任务里的怪兽数
			//printf("%d = %d %d\n",i,a[i].v,a[i].cnt);
		}
		sort(a+1,a+n+1,cmp);
		ans=a[1].v;
		int l=ans+a[1].cnt;
		//排序比较
		for(int i=2;i<=n;i++){
			if(l<a[i].v){
				ans=ans+a[i].v-l;
				l=a[i].v;
			}
			l+=a[i].cnt;
		}
		printf("%d\n",ans);
	}
	return 0;
} 

备注

写入好题本

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

materialistOier

我只是一名ssfoier

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值