(CF1384B2)Koa and the Beach (Hard Version)

做法:贪心

对于每一个永远安全的点,我们都可以在他上面等待到任意时刻,那么当tide到达k时出发,向下一个安全点前进必然是最优的。

证明:
假设一种处于两个安全点中间的状态,这个时候tide已经在上升了,但这个点的深度又超过了限制,那么能否尝试将出发提前,即在上升的时候就出发呢?
由于安全点之间的点的深度+k必然大于限制,那么仍然需要等待,故tide出发时必然最优(改变状态设计好像也可以不从k出发,不过那样就没有一个明确的界线了)

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define Ls t[p<<1]
#define Rs t[p<<1|1]
#define fastio ios::sync_with_stdio(false),cin.tie(NULL),cout.tie(NULL)
const int maxn = 1e6 + 10;
const ll inf = 1e17;

ll mod = 998244353;

int main()
{
    //freopen("C:\\1.in", "r", stdin);
    fastio;
    int t;
    cin >> t;
    while (t--)
    {
        ll n, k, l;
        cin >> n >> k >> l;
        vector<ll>d(n + 1);
        vector<int>saf;//路程中完全安全的点
        saf.push_back(0);
        for (int i = 1; i <= n; i++)
        {
            cin >> d[i];
            if (d[i] + k <= l)saf.push_back(i);
        }
        saf.push_back(n + 1);
        bool flag = 1;
        for (int i = 1; i < saf.size(); i++)
        {
            bool down = 1;
            ll tide = k;//从潮汐从最高往下降时开始贪心
            for (int j = saf[i-1] + 1; j < saf[i]; j++)
            {
                down == 1 ? --tide : ++tide;//当前tide状态
                if (d[j] + tide > l)//waiting。。。
                {
                    if (!down) { flag = 0; break; }//如果已经在上升了
                    tide -= d[j] + tide - l;
                }
                if (tide < 0)//没办法下降到期待高度
                {
                    flag = 0;
                    break;
                }
                if (tide == 0)
                    down = 0;
            }
        }
        if (flag)cout << "Yes" << endl;
        else cout << "No" << endl;
    }
    return 0;

}
posted @ 2020-08-12 11:01  Lecoww  阅读(134)  评论(0编辑  收藏  举报