题目背景 《爱与愁的故事第四弹·plant》第一章。
题目描述 爱与愁大神后院里种了 n 棵樱花树,每棵都有美学值 Ci。
爱与愁大神在每天上学前都会来赏花,爱与愁大神可是生物学霸,他懂得如何欣赏樱花:
一种樱花树看一遍过,一种樱花树最多看 Ai 遍,一种樱花树可以看无数遍。但是看每棵樱花树都有一定的时间 Ti。
爱与愁大神离去上学的时间只剩下一小会儿了。求解看哪几棵樱花树能使美学值最高且爱与愁大神能准时(或提早)去上学。
输入格式 第 1 行:现在时间 Ts (几时:几分),去上学的时间 Te(几时:几分),爱与愁大神院子里有几棵樱花树 n。 这里的 Ts,Te 格式为:hh:mm,其中 0 ≤ hh ≤ 23,0 ≤ mm ≤ 59,且 hh, mm, n 均为正整数
第 2 行到第 n+1 行,每行三个正整数:看完第 i 棵树的耗费时间 Ti,第 i 棵树的美学值 Ci,看第 i 棵树的次数 Pi。 Pi = 0 表示无数次,Pi 是其他数字表示最多可看的次数 Pi
输入样例 6:50 7:00 3 2 1 0 3 3 1 4 5 4
输出样例 11
样例解释 赏第一棵樱花树一次,赏第三棵樱花树 2 次。
数据范围 对于 100% 数据:Te− Ts ≤ 1000(即开始时间距离结束时间不超过 1000 分钟),n ≤ 10000。 保证 Te, Ts 为同一天内的时间。
题解 混合背包:
01背包可以看成是多重背包的特殊情况
#include <iostream> #include <cstdio> using namespace std; const int N = 10010, M = 1010; int T[N], C[N], P[N], f[M]; int n, m, h1, m1, h2, m2; int main() { scanf("%d:%d %d:%d %d", &h1, &m1, &h2, &m2, &n); int m = (h2 - h1) * 60 + m2 - m1; for (int i = 1; i <= n; i ++) cin >> T[i] >> C[i] >> P[i]; for (int i = 1; i <= n; i ++) if(!P[i]) // 完全背包 { for (int j = T[i]; j <= m; j ++) for (int k = 0; k * T[i] <= j; k ++) f[j] = max(f[j], f[j - T[i]] + C[i]); } else // 多重背包 { for (int j = m; j >= T[i]; j --) for (int k = 0; k * T[i] <= j && k <= P[i]; k ++) f[j] = max(f[j], f[j - k * T[i]] + k * C[i]); } cout << f[m] << endl; return 0; }