Codeforces 1257D Yet Another Monster Killing Problem【贪心】


传送门:Codeforces 1257D


D.Yet Another Monster Killing Problem
time limit per test: 2 seconds

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



题目大意:
有 n 个怪兽和 m 个英雄,每个怪兽有一个能力值 a,每个英雄有一个能力值 p 和 耐力值 s。
每天都要派一个英雄去牢房里清理怪兽,只有当该英雄的能力值大于怪兽的能力值时才可以清理掉这个怪兽,每清理一个怪兽,英雄的耐力值会减 1 ,当耐力值减完或者不能打败这个怪兽时这一天便结束。
问最少要花多少天才能打完所有的怪兽。


解题思路:
贪心大体思路:记录每个耐力值下,英雄的最大能力值。为了快速清理完所有的怪兽,就应该优先选择能力值大且耐力值大的英雄。
m x [ i ] : mx[i]: mx[i]: 耐力值为 i 时的最大能力值;
当有一个怪兽的能力值,比所有的英雄能力值都大的时候,就输出 -1;
每次找最大的能力值(一个英雄可以清的怪数)
具体看代码



AC代码:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
const int N=2e5+10;
int t,n,m;
int a[N],p[N],s[N];
int mx[N];
int main()
{
  scanf("%d",&t);
  while(t--)
  {
    //memset(mx,0,sizeof(mx));
    scanf("%d",&n);
    for(int i=0;i<=n;i++) mx[i]=0;
    for(int i=0;i<n;i++)
    {
      scanf("%d",&a[i]);
    }
    scanf("%d",&m);
    for(int i=0;i<m;i++)
    {
      scanf("%d%d",&p[i],&s[i]);
      mx[s[i]]=max(mx[s[i]],p[i]);
    }
    for(int i=n-1;i>=0;i--)
    {
      mx[i]=max(mx[i],mx[i+1]);//可以清i天的英雄,同样可以清 i-1 天
    }
    int day=0,pos=0;
    bool flag=true;
    while(pos<n)
    {
      ++day;
      int tmp=pos;
      int maxn=0;
      while(true)//找最多一个英雄可以清几只怪兽
      {
        maxn=max(maxn,a[tmp]);
        if(maxn>mx[tmp-pos+1])
          break;
        ++tmp;
      }
      if(tmp==pos)
      {
        flag=false;
        break;
      }
      pos=tmp;
    }
    if(!flag)
      day=-1;
    printf("%d\n",day);
  }
  return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值