zoukankan      html  css  js  c++  java
  • Yet Another Monster Killing Problem

    题意:
    有n个怪兽,每个怪兽的战斗力为a[i]。

    有m个英雄,每个英雄都有两个属性pi(战斗力)和si(耐力值),每杀死一个怪兽耐力值-1。

    每天都需要派一个英雄去杀怪兽,如果该英雄的战斗力低于怪兽或者耐力值没了,则这一天结束。
    问你最少多少天能杀完怪兽?

    思路:

    用k[i]数组记录每个耐力值的最大攻击力值

    再按攻击力值填充耐力值为0的地方,比如k[2]=8说明耐力值为2的攻击力为8 没有耐力值为1的所以k[1]=0

    这时 令k[1]=8,说明耐力值为1的攻击力为8,表明当攻击力为8时,我可以攻打一个,也可以攻打两个

    反向填充,耐力值逐渐减少而攻击力取最大值,意在原攻击力匹配k个耐力值,可以都用,或者用一个,或者用两个。。等等

    也会取代耐力值小并且攻击力也小的英雄

                                              for (int i = n; i >= 0; i--) k[i] = max(k[i], k[i + 1]);

    对于每个a[i]与k[1]比较,此时k[1]为英雄攻击力最大值,若是任一a[i]大于k[1]说明无法成功,输出-1。

    之后遍历怪兽的攻击力,取a[i+j]和a[i+j+1]的最大值与英雄耐力值为j+1时的攻击力比较,

    一旦英雄攻击失败,天数++,并且记录此时的i(i为第几只怪兽),再接着遍历

                                              for (; j <= n; j++) {
                                                      maxn = max(maxn, a[j + i]);
                                                      if (k[j + 1] < maxn) break; //因为每个英雄可以无限次使用
                                              }
                                             day++;
                                             i += j;

    按顺序攻击,所以k数组的目的就是在攻击力可以的情况下使耐力尽可能大。

    注意:英雄是按顺序攻击怪兽,若是这个英雄没有攻击成功,下一个英雄第二天继续攻击

              每天都会生成新的耐力值

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<queue>
     6 #include<stack>
     7 #include <bitset>
     8 #include<set>
     9 #include<map>
    10 #include<unordered_map>
    11 #include<vector>
    12 #include<cmath>
    13 #include<string>
    14 using namespace std;
    15 typedef long long ll;
    16 #define inf 99999999
    17 const int maxn = 2e5;
    18 int t, n, m;
    19 int a[maxn], k[maxn];
    20 struct node {
    21     int p;
    22     int s;
    23 }her[maxn];
    24 int main() {
    25     cin >> t;
    26     while(t--){
    27         cin >> n;
    28         for (int i = 1; i <= n; i++) {
    29             cin >> a[i];
    30         }
    31         cin >> m;
    32         for (int i = 1; i <= m; i++) {
    33             cin >> her[i].p >> her[i].s;
    34             //记录每个耐力值的最大攻击力值
    35             k[her[i].s] = max(k[her[i].s], her[i].p);
    36         }
    37         for (int i = n; i >= 0; i--) k[i] = max(k[i], k[i + 1]);
    38         int day = 0;
    39         int f = 0;
    40         for (int i = 1; i <= n;) {
    41             if (a[i] > k[1]) {
    42                 f = 1;
    43                 cout << "-1" << endl;
    44                 break;
    45             }
    46             int j = 0;
    47             int maxn = 0;
    48             for (; j <= n; j++) {
    49                 maxn = max(maxn, a[j + i]);
    50                 if (k[j + 1] < maxn) break; //因为每个英雄可以无限次使用
    51             }
    52             day++;
    53             i += j;
    54         }
    55         if (f == 0) {
    56             cout << day << endl;
    57         }
    58         for (int i = 0; i <= n; i++) k[i] = 0;
    59     }
    60     return 0;
    61 }
  • 相关阅读:
    springboot访问redis序列化问题
    观察者模式在源码中的使用
    抽象工厂模式在源码中的使用
    工厂方法模式在源码中的应用
    策略模式的应用
    springcloud实现限流
    Elasticsearch
    java8新特性(二)StreamApi
    thinkpaidE450 win10 进入bios
    restframe_work2
  • 原文地址:https://www.cnblogs.com/0211ji/p/13388382.html
Copyright © 2011-2022 走看看