洛谷P1833 樱花

(Large extbf{Description: } large{n个物品,每个物品有重量、价值、数量,求能容纳重量k下最大价值。(k leq 1000, n leq 10000)}\)

(Large extbf{Solution: } large{一道背包题,主要是需要二进制分解。}\)

(Large extbf{Code: })

#include <cstdio>
#include <algorithm>
#define LL long long
#define gc() getchar()
#define rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define _rep(i, a, b) for (int i = (a); i >= (b); --i)
using namespace std;
const int N = 10000005;
int n, cnt, x1, x2, y1, y2, a[N], b[N], c[N], f[N], cost[N], val[N];

inline int read() {
	char ch = gc();
	int ans = 0;
	while (ch > '9' || ch < '0') ch = gc();
	while (ch >= '0' && ch <= '9') ans = (ans << 1 ) + (ans << 3) + ch - '0', ch = gc();
	return ans;
}

inline void sol() {
	rep(i, 1, n) {
		int t = 1;
		while (c[i]) {
			cost[++cnt] = t * a[i];
			val[cnt] = t * b[i];
			c[i] -= t, t <<= 1;
			if (c[i] < t) {
				cost[++cnt] = a[i] * c[i];
				val[cnt] = b[i] * c[i];
				break;
			}
		}
	}	
}

int main() {
	scanf("%d:%d%d:%d", &x1, &y1, &x2, &y2), n = read(); 
	int  t = x2 * 60 + y2 - (x1 * 60 + y1);
	rep(i, 1, n) {
		a[i] = read(), b[i] = read(), c[i] = read();
		c[i] = c[i] == 0 ? 9999999 : c[i];//如果一个东西无限量的话 我们设一个特别大的值
	}
	sol();
	rep(i, 1, cnt)
		_rep(j, t, cost[i])
			f[j] = max(f[j], f[j - cost[i]] + val[i]);	
	printf("%d
", f[t]);
	return 0;	
} 
原文地址:https://www.cnblogs.com/Miraclys/p/12490710.html