有N颗树,第i颗树上有(c_i)只鸟,召唤师每召唤一只该树上的鸟,法力上限增加B(常数),消耗法力(cost_i)
召唤师从第1颗树到第N颗,每到一棵树回复法力值X,求最多召唤多少只鸟
input: (n, W, B, X(1 leq n leq 10^3, 0 leq W, B, X, leq 10^9))
(c_1, c_2...c_n(0 leq c_i leq 10^4))
(cost_1, cost_2...cost_n(0 leq cost_i leq 10^9))
第一想法显然用(dp[N][sum c_i])表示最终答案
显然需要想明白,这个复杂度是可以接受的
虽然是三重循环,但复杂度只有(O(nsum _{i=1} ^n c_i))
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int maxn = 1e3 + 10;
const int maxm = 1e4 + 10;
int A[maxn], cost[maxn];
LL dp[maxn][maxm];
int sum, ans;
LL N, W, B, X;
int main() {
scanf("%lld%lld%lld%lld", &N, &W, &B, &X);
for (int i = 1; i <= N; i++) scanf("%d", &A[i]), sum += A[i];
for (int i = 1; i <= N; i++) scanf("%d", &cost[i]);
memset(dp, -1, sizeof(dp)); ans = 0;
dp[0][0] = W;
for (int i = 1; i <= N; i++) {
for (int j = 0; j <= sum; j++) {
for (int k = 0; k <= min(j, A[i]); k++) {
if (dp[i - 1][j - k] == -1) continue;
LL t = min(W + (j - k) * B, dp[i - 1][j - k] + X) - (LL)cost[i] * k;
if (t < 0) continue;
dp[i][j] = max(dp[i][j], min(W + j * B, t));
ans = max(ans, j);
}
}
}
printf("%d
", ans);
return 0;
}