FZUOJ 2214-CSDN博客

25 阅读1分钟

acm.fzu.edu.cn/problem.php…

大容量背包逆向思维

#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring> 
using namespace std;
const int maxn = 507;
int dp[maxn + 1];
int w[maxn], v[maxn];
int main()
{
	int T;
	scanf("%d", &T);
	while (T--) {

		int n, B, V = 0;
		scanf("%d%d", &n, &B);
		for (int i = 0; i < n; ++i) { //重量不超过B, sum (v) <= 5000
			scanf("%d%d", w + i, v + i);
			V += v[i];
		}
		memset(dp, 0x3f, sizeof dp);
		dp[0] = 0; //就错在dp这 
		for (int i = 0; i < n; ++i) {
			for (int j = V; j >= v[i]; --j) { //dp[j]表示装价值为j时所需的最小容量 
				if (dp[j - v[i]] + w[i] <= B) { //所需容量尽量小 
					dp[j] = min(dp[j], dp[j - v[i]] + w[i]);
				}
			}
		}
		int ans = -1;
		for (int j = V; j >= 0; --j) {
			printf("dp[%d] = %d\n", j, dp[j]);
			if (dp[j] <= B) {
				ans = j;
				break;
			}
		}
		printf("%d\n", ans); //价值, dp[j]为重量,dp[j]的价值为j
	}

	return 0;
}


\