https://vjudge.net/problem/CodeForces-1257Dios
你須要操做m個英雄去戰勝n只怪物,每一個英雄的力量值爲pi,能夠戰勝si只怪物;每隻怪物的力量值爲ai。c++
當新的一天開始時,你能夠選擇其中1個英雄去打怪。若在以前已有k只怪物被戰勝,這個英雄將挑戰第k+1只怪物,此時有兩種狀況:數組
1.英雄力量≤怪物力量,則英雄撤退,這一天結束。spa
2.英雄力量>怪物力量,怪物被戰勝。繼續挑戰下一隻怪物。當n只怪物所有被戰勝,或該英雄已戰勝的怪物數量=si時,這一天結束。.net
你的任務是計算出戰勝全部怪物所須要的最小天數。指針
最簡單的想法就是用si大的儘量多打。blog
維護每一個耐力值si對應的力量最大的英雄,由於相等耐力值狀況下確定是選力量最大的要好。ci
再維護上面數組的後綴最大值,這個其實就是耐力值少的也能夠(注意是能夠!不是必定)用耐力值大的代替,好比對於耐力值i,i+1,若是i+1的力量大於i,那麼徹底能夠用i+1代替i去打,由於耐力值比i大。get
而後用雙指針求解,當前遍歷到第i個怪物,用j往右邊延伸,看最遠能打到哪一個怪物,這裏要實時記錄這一段怪物力量的最大值,若是v[j-i+1]>=mx (v是上述處理完後綴最大值後的數組),那麼就能夠延伸,v[j-i+1]表示耐力值爲j-i+1~n(這一段的耐力值大於mx的英雄均可以使用)的最大英雄力量值。it
#include<bits/stdc++.h> using namespace std; #define inf 0x3f3f3f3f #define ll long long const int N=200005; const int mod=1e9+7; const double eps=1e-8; const double PI = acos(-1.0); #define lowbit(x) (x&(-x)) int a[N],v[N]; int main() { std::ios::sync_with_stdio(false); int t; cin>>t; while(t--) { int n; cin>>n; for(int i=1;i<=n;i++) { cin>>a[i]; v[i]=0; } int m; cin>>m; for(int i=1;i<=m;i++) { int p,s; cin>>p>>s; v[s]=max(v[s],p); } for(int i=n-1;i>=1;i--) { v[i]=max(v[i],v[i+1]); } int i=1,j,ans=0,flag=0; while(i<=n) { if(a[i]>v[1]) { flag=1; break; } j=i; int mx=a[i]; while(j<=n&&v[j-i+1]>=mx) { j++; mx=max(mx,a[j]); } ans++; i=j; // cout<<i<<" "<<ans<<endl; } if(flag) cout<<-1<<endl; else cout<<ans<<endl; } return 0; }