樱花(洛谷)

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

猜你喜欢

转载自blog.csdn.net/weixin_46239370/article/details/108951863
今日推荐