• 「日常训练」Single-use Stones (CFR476D2D)


    题意(Codeforces 965D)

    $w$表示河的宽度,$l$表示青蛙所能跳的最远的距离,第二行的$w-1$个元素表示离河岸为$i$的地方有$a[i]$个石头,一个石头被踩两次,问最多有多少只青蛙可以跳到河对岸。

    分析

    我是激情看题解的,很惭愧。因为自己的算法喜提TLE了w
    我参考的题解在这儿。官方题解用了二分的思想。
    这个算法是怎么贪心的呢?就在 while(p<i && frog[p]+frog[i]<=a[i]) 这一句。当第$i$处已经满了的时候,我们就不考虑$[p+1,i-1]$到$i$的跳跃了。后面那句if是减去多余的。其他地方结合注释和原题解的讲解来看。注意维护$p$指针始终和$i$的距离$<l$。

    代码

    #include<bits/stdc++.h>
    
    #define inf 0x3f3f3f3f
    #define PB push_back
    #define MP make_pair
    #define fi first
    #define se second
    #define lowbit(x) (x&(-x))
    #define rep(i, a, b) for(int i = (a); i <= (b); i++)
    #define per(i, a, b) for(int i = (a); i >= (b); i--)
    #define pr(x) cout << #x << " = " << x << " ";
    #define prl(x) cout << #x << " = " << x << endl;
    #define ZERO(X) memset((X),0,sizeof(X))
    #define ALL(X) (X).begin(),(X).end()
    #define SZ(x) (int)x.size()
    
    using namespace std;
    
    typedef pair<int, int> PI;
    typedef pair<pair<int, int>, int> PII;
    typedef pair<pair<pair<int, int>, int>, int> PIII; 
    using ull= unsigned long long;
    using ll = long long;
    using ld = long double;
    #define quickio ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
    #define debug(...) fprintf(stderr, __VA_ARGS__), fflush(stderr)
    /*      debug("Precalc: %.3f
    ", (double)(clock()) / CLOCKS_PER_SEC);
    clock_t z = clock();
            solve();
            //debug("Test: %.3f
    ", (double)(clock() - z) / CLOCKS_PER_SEC);
    */
    template<typename T = int>
    inline T read() {
        T val=0, sign=1;
        char ch;
        for (ch=getchar();ch<'0'||ch>'9';ch=getchar())
            if (ch=='-') sign=-1;
        for (;ch>='0'&&ch<='9';ch=getchar())
            val=val*10+ch-'0';
        return sign*val;
    }
    
    int main()
    {
        int w,l; cin>>w>>l;
        int a[100005]; ZERO(a);
        int frog[100005]; ZERO(frog);
        a[w]=0x3f3f3f3f; // INF
        rep(i,1,w-1)
        {
            cin>>a[i];
            if(i<=l) frog[i]=a[i];
        }
    
        int p=1;
        rep(i,l+1,w)
        {
            while(i-p>l) ++p;
            while(p<i && frog[p]+frog[i]<=a[i])
                frog[i]+=frog[p++];
            if(p<i&&frog[i]!=a[i]) // greedy here. It's impossible for p+1~i-1 to jmp to a[i]. here, imply that frog[p]+frog[i]>a[i]
            {
                frog[p]-=(a[i]-frog[i]); // the a[i]-frog[i] frogs cannot jmp from p, because it's full already.
                frog[i]=a[i];
            }
        }
        cout<<frog[w]<<endl;
        return 0;
    }
    如非注明,原创内容遵循GFDLv1.3发布;其中的代码遵循GPLv3发布。
  • 相关阅读:
    根据百度API获得经纬度,然后根据经纬度在获得城市信息
    Map实现java缓存机制的简单实例
    JMS学习(七)-ActiveMQ消息的持久存储方式之KahaDB存储
    JMS学习(六)-ActiveMQ的高可用性实现
    排列与组合的一些定理
    带权图的最短路径算法(Dijkstra)实现
    JMS学习(六)--提高非持久订阅者的可靠性 以及 订阅恢复策略
    JMS学习(五)--ActiveMQ中的消息的持久化和非持久化 以及 持久订阅者 和 非持久订阅者之间的区别与联系
    分布式系统理论之两阶段提交协议
    自定义栈的实现及使用两个栈模拟队列
  • 原文地址:https://www.cnblogs.com/samhx/p/cfr476d2d.html
Copyright © 2020-2023  润新知