模拟加贪心
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int maxn = 1111;
struct node {
int area, num, income, next_ripe;
node(int area = 0, int num = 0, int income = 0, int next_ripe = 0) :
area(area), num(num), income(income), next_ripe(next_ripe) {
}
} f[10];
int Q[maxn], P[maxn], N[maxn], M[maxn];
int NUM[10], cnt[10], area[10];
LL go(int money, int D, int Q, int P, int period) {
int j, day = 0, more;
LL have = money, income;
while (day <= D) {
if (day + period > D)
break;
income = 0;
for (j = 0; j < 5; ++j) {
if (f[j].income <= Q)
continue;
more = have / Q;
more = min(more, NUM[j]);
have -= 1LL * Q * more;
income += 1LL * P * more * f[j].area;
}
have += income;
day += period;
}
return have;
}
LL go(int money, int D, int Q, int P, int N, int M) {
int j, day = 0, delta = 0, more;
LL income;
LL have = money;
int remain[10];
LL tmp = 0;
copy(NUM, NUM + 10, remain);
vector<node> v;
vector<node>::iterator it;
int cultivate = 0;
while (day <= D) {
income = 0;
LL now = have;
for (j = 0; j < 5; ++j) {
more = now / Q;
more = min(more, remain[j]);
if (more > 0 && day + N <= D) {
LL harvest_times = (D - day - N) / M + 1;
if (harvest_times * P * area[j] > Q) {
v.push_back(node(area[j], more, f[j].income, N));
now -= 1LL * Q * more;
cultivate += more;
remain[j] -= more;
}
}
}
delta = 44444444;
for (it = v.begin(); it != v.end(); ++it)
delta = min(delta, it->next_ripe);
if (day + delta > D)
break;
day += delta;
income = 0;
for (it = v.begin(); it != v.end(); ++it) {
it->next_ripe -= delta;
if (it->next_ripe == 0) {
income += 1LL * it->income * it->num;
it->next_ripe = M;
}
}
tmp += income;
have = now + income;
}
return have;
}
int main() {
int w, h, A, D, Y, i, a, b, j;
int T;
scanf("%d", &T);
while (T--) {
scanf("%d %d %d %d %d", &w, &h, &A, &D, &Y);
a = w % 3, b = h % 3;
NUM[0] = (w / 3) * (h / 3);
NUM[1] = 1;
NUM[2] = h / 3 - 1;
NUM[3] = w / 3 - 1;
NUM[4] = 2;
area[0] = 9;
area[1] = 3 * (a + b) - a * b;
area[2] = a * 3;
area[3] = b * 3;
area[4] = a * b;
if (a < b) {
swap(NUM[2], NUM[3]);
swap(a, b);
swap(area[2], area[3]);
}
LL ans = Y;
for (i = 0; i < A; ++i) {
scanf("%d%d%d%d", Q + i, P + i, N + i, M + i);
for (j = 0; j < 5; ++j) {
f[j] = node(area[j], 0, P[i] * area[j], N[i]);
}
if (!M[i])
ans = max(ans, go(Y, D, Q[i], P[i], N[i]));
else
ans = max(ans, go(Y, D, Q[i], P[i], N[i], M[i]));
}
printf("%I64d\n", ans);
}
return 0;
}