zoukankan      html  css  js  c++  java
  • CodeForces-1257D (贪心+双指针)

    题意

    https://vjudge.net/problem/CodeForces-1257D

    你需要操作m个英雄去打败n只怪物,每个英雄的力量值为pi,可以打败si只怪物;每只怪物的力量值为ai。

    当新的一天开始时,你可以选择其中1个英雄去打怪。若在之前已有k只怪物被打败,这个英雄将挑战第k+1只怪物,此时有两种情况:

    1.英雄力量≤怪物力量,则英雄撤退,这一天结束。

    2.英雄力量>怪物力量,怪物被打败。继续挑战下一只怪物。当n只怪物全部被打败,或该英雄已打败的怪物数量=si时,这一天结束。

    你的任务是计算出打败所有怪物所需要的最小天数。

    思路

    最简单的想法就是用si大的尽可能多打。

    维护每个耐力值si对应的力量最大的英雄,因为相等耐力值情况下肯定是选力量最大的要好。

    再维护上面数组的后缀最大值,这个其实就是耐力值少的也可以(注意是可以!不是一定)用耐力值大的代替,比如对于耐力值i,i+1,如果i+1的力量大于i,那么完全可以用i+1代替i去打,因为耐力值比i大。

    然后用双指针求解,当前遍历到第i个怪物,用j往右边延伸,看最远能打到哪个怪物,这里要实时记录这一段怪物力量的最大值,如果v[j-i+1]>=mx (v是上述处理完后缀最大值后的数组),那么就可以延伸,v[j-i+1]表示耐力值为j-i+1~n(这一段的耐力值大于mx的英雄都可以使用)的最大英雄力量值。

    代码

    #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;
    }
    

      

  • 相关阅读:
    CodeForces
    bzoj 2257: [Jsoi2009]瓶子和燃料
    【NOIP2009】Hankson 的趣味题
    51Nod 1203 JZPLCM
    bzoj 3751: [NOIP2014]解方程
    UOJ #11. 【UTR #1】ydc的大树
    Tenka1 Programmer Contest D
    bzoj 5000: OI树
    bzoj 1407: [Noi2002]Savage
    bzoj 3551: [ONTAK2010]Peaks加强版
  • 原文地址:https://www.cnblogs.com/mcq1999/p/11887403.html
Copyright © 2011-2022 走看看