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