洛谷P1833 樱花
\(\Large\textbf{Description: } \large{n个物品,每个物品有重量、价值、数量,求能容纳重量k下最大价值。(k \leq 1000, n \leq 10000)}\\\)
\(\Large\textbf{Solution: } \large{一道背包题,主要是需要二进制分解。}\\\)
\(\Large\textbf{Code: }\)
#include <cstdio>
#include <algorithm>
#define LL long long
#define gc() getchar()
#define rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define _rep(i, a, b) for (int i = (a); i >= (b); --i)
using namespace std;
const int N = 10000005;
int n, cnt, x1, x2, y1, y2, a[N], b[N], c[N], f[N], cost[N], val[N];
inline int read() {
char ch = gc();
int ans = 0;
while (ch > '9' || ch < '0') ch = gc();
while (ch >= '0' && ch <= '9') ans = (ans << 1 ) + (ans << 3) + ch - '0', ch = gc();
return ans;
}
inline void sol() {
rep(i, 1, n) {
int t = 1;
while (c[i]) {
cost[++cnt] = t * a[i];
val[cnt] = t * b[i];
c[i] -= t, t <<= 1;
if (c[i] < t) {
cost[++cnt] = a[i] * c[i];
val[cnt] = b[i] * c[i];
break;
}
}
}
}
int main() {
scanf("%d:%d%d:%d", &x1, &y1, &x2, &y2), n = read();
int t = x2 * 60 + y2 - (x1 * 60 + y1);
rep(i, 1, n) {
a[i] = read(), b[i] = read(), c[i] = read();
c[i] = c[i] == 0 ? 9999999 : c[i];//如果一个东西无限量的话 我们设一个特别大的值
}
sol();
rep(i, 1, cnt)
_rep(j, t, cost[i])
f[j] = max(f[j], f[j - cost[i]] + val[i]);
printf("%d\n", f[t]);
return 0;
}