P1833 樱花 背包DP 多重背包 , 混合背包
混合背包是指很多种背包一起做。此题属于多重背包的模板题
思想是统统转化为01背包
题目中有01背包(p = 1),完全背包(p = 0) , 多重哦背包 (p = k)
完全背包,只需将p = t / w 。
多重背包,只需进行二进制拆分
注意数组开大
int readint() { int x = 0, f = 1; char ch = getchar(); while (ch < '0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); } while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); } return x * f; } ll readll() { ll x = 0, f = 1; char ch = getchar(); while (ch < '0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); } while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); } return x * f; } void Put(int x) { if (x > 9) Put(x / 10); putchar(x % 10 + '0'); } int dp[maxn]; int val[maxn]; int w[maxn]; int p[maxn]; int main() { int t1, t2, t3, t4, n; scanf("%d:%d %d:%d %d", &t1, &t2, &t3, &t4, &n); int t = (t1 * 60 + t2 ); t = -1 * t + (t3 * 60 + t4 ); for (int i = 0; i < n; i++) w[i] = readint(), val[i] = readint(), p[i] = readint(); int tot = n - 1; for (int i = 0; i < n; i++) { if (p[i] == 1) continue; if (!p[i]) p[i] = t / w[i] + 2; int _p = p[i] - 1; for (int j = 2; j <= _p; j <<= 1) { _p -= j; w[++tot] = j * w[i]; val[tot] = j * val[i]; } if (_p) { w[++tot] = _p * w[i]; val[tot] = _p * val[i]; } } for (int i = 0; i <= tot; i++) { for (int j = t; j >= w[i]; j--) { dp[j] = max(dp[j], dp[j - w[i]] + val[i]); } } Put(dp[t]); }