Codeforces 922E

有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(n\sum _{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\n", ans);
	return 0;
}
posted @ 2018-08-28 21:36  xFANx  阅读(229)  评论(0编辑  收藏  举报