1. 程式人生 > >Luogu 3957 [NOIP2017]普及組 跳房子

Luogu 3957 [NOIP2017]普及組 跳房子

\n += getchar() 取值 gif const pre 滑動窗口 tdi

寫了好久,感覺自己好菜,唉……

首先發現這個$g$的取值具有單調性,可以想到二分答案,然後考慮用$dp$來檢驗,這樣子可以寫出樸素的轉移方程:

  設$f_i$表示以$i$結尾的最大價值,那麽有$f_i = max(f_j) + val_i$  $(0 < j < i)$  $((dis_i - (d + g) \leq dis_j \leq dis_i - max(d - g, 1)))$。

然後註意到是選取一個滑動窗口的最大值,用一個單調隊列優化一下就可以了。

時間復雜度$O(nlogn)$。

註意開$long\ long$。

Code:

技術分享圖片
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;

const int N = 5e5 + 5;
const ll inf = 1LL << 60;

int n, d, dis[N], q[N];
ll cur, val[N], f[N];

template <typename T>
inline void read(T &X) {
    X = 0; char ch = 0; T op = 1
; for(; ch > 9 || ch < 0; ch = getchar()) if(ch == -) op = -1; for(; ch >= 0 && ch <= 9; ch = getchar()) X = (X << 3) + (X << 1) + ch - 48; X *= op; } template <typename T> inline void chkMax(T &x, T y) { if
(y > x) x = y; } template <typename T> inline int max(T x, T y) { return x > y ? x : y; } inline bool chk(int mid) { int st = max(1, d - mid), ed = d + mid, l = 1, r = 0; memset(f, 0LL, sizeof(f)); for(int j = 0, i = 1; i <= n; i++) { for(; j < i && dis[j] <= dis[i] - st; j++) { for(; l <= r && f[q[r]] < f[j]; --r); q[++r] = j; } for(; l <= r && dis[q[l]] < dis[i] - ed; ++l); ll mx = f[q[l]]; if(l > r) mx = -inf; f[i] = mx + val[i]; if(f[i] >= cur) return 1; } return 0; } /*inline bool chk(int mid) { int st = max(1, d - mid), ed = d + mid; memset(f, 0, sizeof(f)); for(int i = 1; i <= n; i++) { int res = -inf; for(int j = 0; j < i; j++) if(dis[j] >= dis[i] - ed && dis[j] <= dis[i] - st) chkMax(res, f[j]); f[i] = res + val[i]; if(f[i] >= cur) return 1; } return 0; } */ int main() { read(n), read(d), read(cur); int mn = 0; ll sum = 0; for(int i = 1; i <= n; i++) { read(dis[i]), read(val[i]); chkMax(mn, dis[i]); if(val[i] > 0) sum += val[i]; } if(sum < cur) return puts("-1"), 0; int ln = 0, rn = mn, mid, res = -1; for(; ln <= rn; ) { mid = (ln + rn) / 2; if(chk(mid)) rn = mid - 1, res = mid; else ln = mid + 1; } printf("%d\n", res); return 0; }
View Code

Luogu 3957 [NOIP2017]普及組 跳房子