题解 CF922E 【Birds】

ChthollyTree

2019-07-13 23:07:18

Solution

我怕不是数据结构学傻了qwq,就这题也能写过数据结构优化dp dp题 $f[i][j]$表示到第$i$棵树,召唤了$j$只鸟所剩下的能量最大值 那么我们可以很容易得到方程 $f[i][j] = max(f[i-1][k] -(j-k)*cost[i])+X(j-c[i]<=k<=j)$ 这时候直接暴力的话会TLE 但是我们可以用st表优化 $f[i][j] = max(f[i-1][k] + k*cost[i]-j*cost[i])+X$ $ = max(f[i-1][k] + k*cost[i])-j*cost[i]+X$ 所以我们用st表维护$f[i-1][k] + k*cost[i]$的区间最大值就行了qwq 转移的时候询问$[j-c[i],j]$的最大值即可 这样写可能常数有点大(我的代码最慢接近800ms) ``` #include<bits/stdc++.h> using namespace std; #define int long long #define MAXN 1005 #define MAXC 10005 #define max(x,y) (x)>(y)?(x):(y) const int INF = (int)0x3f3f3f3f*(int)0x3f3f3f3f; int n,W,B,X,C; int c[MAXN]; int f[MAXN][MAXC],g[MAXN][MAXC]; int s[MAXC][20]; int cost[MAXN]; inline void jianbiao(int ii) { for(int i = 0; i <= C; i ++) s[i][0] = f[ii][i] + cost[ii+1]*i; for(int j = 1; j <= 17; j ++) for(int i = 0; i+(1<<j) <= C; i ++) { s[i][j] = max(s[i][j-1],s[i+(1<<(j-1))][j-1]); } } inline int rmq(int l,int r) { if(l < 0) l = 0; int o = log2(r-l+1); return max(s[l][o],s[r-(1<<o)+1][o]); } void rd() { cin >> n >> W >> B >> X; for(int i = 1; i <= n; i ++) { cin >> c[i]; C += c[i]; } for(int i = 1; i <= n; i ++) cin >> cost[i]; } signed main() { rd(); f[0][0] = W; g[0][0] = W; for(int i = 1; i <= C; i ++) { f[0][i] = -INF; g[0][i] = -INF; } jianbiao(0); for(int i = 1; i <= n; i ++) { for(int j = 0; j <= C; j ++) { f[i][j] = rmq(j-c[i],j) - j*cost[i] + X; if(f[i][j] < X) f[i][j] = -INF; if(f[i][j] > W+j*B) f[i][j] = W+j*B; } jianbiao(i); } int ans = 0; for(int i = 0; i <= C; i ++) if(f[n][i] >= 0) ans = i; cout<<ans; return 0; } ```