题目背景
《爱与愁的故事第四弹·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;
}