(CF1384B2)Koa and the Beach (Hard Version)
阿新 • • 發佈:2020-08-12
做法:貪心
對於每一個永遠安全的點,我們都可以在他上面等待到任意時刻,那麼當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; }