Educational Codeforces Round 76 D. Yet Another Monster Killing Problem(贪心)

本文探讨了一个游戏策略问题,玩家需利用不同能力的英雄,通过合理分配,以最少的天数清扫地牢中的怪物。文章分析了如何记录各耐力值对应的最大力量,以此选择每日出战英雄,确保效率最大化。
题目描述

You play a computer game. In this game, you lead a party of m heroes, and you have to clear a dungeon with n monsters. Each monster is characterized by its power ai. Each hero is characterized by his power pi and endurance si.
The heroes clear the dungeon day by day. In the beginning of each day, you choose a hero (exactly one) who is going to enter the dungeon this day.
When the hero enters the dungeon, he is challenged by the first monster which was not defeated during the previous days (so, if the heroes have already defeated k monsters, the hero fights with the monster k+1). When the hero fights the monster, there are two possible outcomes:
if the monster’s power is strictly greater than the hero’s power, the hero retreats from the dungeon. The current day ends;
otherwise, the monster is defeated.
After defeating a monster, the hero either continues fighting with the next monster or leaves the dungeon. He leaves the dungeon either if he has already defeated the number of monsters equal to his endurance during this day (so, the i-th hero cannot defeat more than si monsters during each day), or if all monsters are defeated — otherwise, he fights with the next monster. When the hero leaves the dungeon, the current day ends.
Your goal is to defeat the last monster. What is the minimum number of days that you need to achieve your goal? Each day you have to use exactly one hero; it is possible that some heroes don’t fight the monsters at all. Each hero can be used arbitrary number of times.

Input

The first line contains one integer t (1≤t≤105) — the number of test cases. Then the test cases follow.
The first line of each test case contains one integer n (1≤n≤2⋅105) — the number of monsters in the dungeon.
The second line contains n integers a1, a2, …, an (1≤ai≤109), where ai is the power of the i-th monster.
The third line contains one integer m (1≤m≤2⋅105) — the number of heroes in your party.
Then m lines follow, each describing a hero. Each line contains two integers pi and si (1≤pi≤109, 1≤si≤n) — the power and the endurance of the i-th hero.
It is guaranteed that the sum of n+m over all test cases does not exceed 2⋅105.

Output

For each test case print one integer — the minimum number of days you have to spend to defeat all of the monsters (or −1 if it is impossible).

Example

input
2
6
2 3 11 14 1 8
2
3 2
100 1
5
3 5 100 2 3
2
30 5
90 1
output
5
-1

题目大意

你有m个英雄,第i个英雄有力量p[i]和耐力s[i]。你想去清理一个有n个怪物的地牢,每个怪物的力量是a[i]。
每天你可以派一名英雄去地牢,英雄会去挑战之前没有打过的第一只怪物。如果该英雄的力量大于这个怪物的力量,那么英雄就会打败它,否则他会撤退。每打败一只怪物,英雄的耐力会减一,当英雄的耐力为0或者地牢的怪全被打完时或者这只怪物的力量大于该英雄的力量时,该英雄会撤退。
问清理地牢最少要花多少天。

题目分析

记录每个耐力值所对应的的最大力量。
ma[i] //表示耐力值为i的情况下,所能获取的最大力量是多少。每次选择耐力足够且力量最大的,当一个英雄的力量小于打败怪物所需要的力量时,则退出洞穴。
当某个怪兽的力量大于英雄力量的最大值时,输出-1。

代码如下
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <stack>
#include <map>
#include <queue>
#include <vector>
#include <set>
#include <algorithm>
#include <iomanip>
#define LL long long
using namespace std;
const int N=2e5+5;
int a[N],p[N],s[N],ma[N];
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		int n,m;
		scanf("%d",&n);
		for(int i=1;i<=n;i++)
			scanf("%d",&a[i]);
		
		scanf("%d",&m);
		for(int i=1;i<=m;i++)
		{
			scanf("%d %d",&p[i],&s[i]);
			ma[s[i]]=max(ma[s[i]],p[i]);	//如果两个英雄的耐力值相同,则保留力量大的
		}
		for(int i=n-1;i>=0;i--) ma[i]=max(ma[i],ma[i+1]);	//找到每个耐力值所能获取的最大力量
		int day=0;
		bool st=true;
		for(int i=1;i<=n;)
		{
			if(a[i]>ma[0])	//如果当前怪物的力量大于所有英雄,则无解,输出-1
			{
				st=false;
				puts("-1");
				break;
			}
			int j,maxv=0;
			for(j=0;j+i<=n;j++)
			{
				maxv=max(maxv,a[j+i]);		//记录完成当前的探索需要的力量最小是多少
				if(ma[j+1]<maxv) break;		//如果当前耐力所对应的力量小于maxv,则这一天的探索结束
			}
			i+=j;	//这一天打了j个怪
			day++;
		}
		if(st) cout<<day<<endl;
		
		for(int i=0;i<=n;i++) ma[i]=0;		//清空ma数组,不能用memset(别问我怎么知道的)
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

lwz_159

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值