混合背包_i++ 每种物品有多件或无限件可选

接收数据的同时把完全背包dp掉,并且对多重背包进行二进制优化,最后再dp多重背包
混合背包_多重背包_02

#include<stdio.h>
#include<algorithm>
#pragma warning(disable:4996)
using namespace std;

int hh1, mm1, hh2, mm2, T, n;
struct info {
	int t;
	int c;
	int p;
}a[10005];
int dp[1005], tt[1000005], cc[1000005], d, e;

int main()
{
	scanf("%d:%d %d:%d %d", &hh1, &mm1, &hh2, &mm2, &n);
	T = hh2 * 60 + mm2 - (hh1 * 60 + mm1);
	for (int i = 0; i < n; i++)
	{
		scanf("%d%d%d", &a[i].t, &a[i].c, &a[i].p);
		if (a[i].p == 0)
		{
			for (int j = a[i].t; j <= T; j++)
			{
				dp[j] = max(dp[j], dp[j - a[i].t] + a[i].c);
			}
		}
		else
		{
			for (int j = 1; j <= a[i].p; j <<= 1)
			{
				tt[d++] = j * a[i].t;
				cc[e++] = j * a[i].c;
				a[i].p -= j;
			}
			if (a[i].p) tt[d++] = a[i].p * a[i].t, cc[e++] = a[i].p * a[i].c;
		}
	}
	for (int j = 0; j < d; j++)
	{
		for (int k = T; k >= tt[j]; k--)
		{
			dp[k] = max(dp[k], dp[k - tt[j]] + cc[j]);
		}
	}
	printf("%d\n", dp[T]);
	return 0;
}