Codeforces Round #599 D Yet Another Monster Killing Problem

机灵点的模拟。 

首先是英雄的最优模拟的数组:第一天的最优力量、第二天的最优力量... (  这样形成的就是一个偏序集合,复杂度O(n+m)  ,因为耐力不是很大,所以可以ac)

其次是要维护一个rmq,否则会犯了比赛中的错误。

 

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

const int maxn = 2e5+500;
//要筛选出一个有用的偏序集合的时候,貌似是排序然后单调栈是最好理解的。
//在这题中,因为维度s的取值范围足够小,可以不进行排序而使用dp来进行转移,
//具体做法就是在每个耐力值上打上最大的pi标记,然后从n向1传递pi,
//这样形成的就是一个偏序集合,复杂度O(n+m)。

int a[maxn],b[maxn];

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    int T;
    cin>>T;
    int n,m;
    while(T--){
        cin>>n;
        for(int i=1; i<=n; i++){
            cin>>a[i];
        }
        cin>>m;
        //int p[maxn];   //p是力量数组,下标是耐力,值是力量,这样就可以扫一遍处理出各种英雄的使用情况    
                       //利用了数组下标上升自动排序的特性
        // memset(p, -1, sizeof(p));
        vector<int> p(n+2);
        int pi,si;
        for(int i=1; i<=m; i++){
            cin>>pi>>si;
            p[ si ] = max(p[ si ], pi);
        }
        for(int i=n-1; i>=1; i--){
            p[i] = max(p[i], p[i+1]);
        }
        int i=1,rmq = -1,ans=0,cnt=1;
        while(i <= n){
            rmq = max(rmq, a[i]);
            if(p[cnt] < rmq){
                if(p[1] < rmq){
                    ans = -2;
                    break;
                }
                rmq = -1;
                cnt = 0;
                ++ans;
                --i;
            }
            ++cnt;
                // cout<<"cnt="<<cnt<<" rmq="<<rmq<<endl;
            ++i;
        }
        cout<<ans+1<<endl;
    }

}

 

posted @ 2019-11-19 21:35  *Zzz  阅读(206)  评论(0编辑  收藏  举报