洛谷 P2347 砝码称重 题解

一道水题。。。
实际上是一道多重背包,主要思路是将多重背包中的每一个物品拆出来,于是就变成01背包模板。这里定义状态为 f [ i ] f[i] f[i] 表示 i i i的体积是否出现过。

#include 
using namespace std;
int num[1010];
int v, a, n, ans;
bool dp[1010];
int b[7]={0, 1, 2, 3, 5, 10, 20};
int main () {
	for(int i = 1; i <= 6; i++) {
		cin >> a;
		for(int j = 1; j <= a; j++) {
			num[++n] = b[i];
			v += num[n];
		}
	}
	dp[0] = true;
	for(int i = 1; i <= n; i++) {
		for(int j = v; j >= 0; j--) {
			if(dp[j]) {
				dp[j + num[i]] = true;
			}
		}
	}
	for(int i = 1; i <= v; i++) {
		if(dp[i]) ans++;
	}
	cout << "Total=" << ans << '\n';
	return 0;
} 

当然,也可以直接用多重背包做:

#include 
using namespace std;
int num[7];
int v, a, n, ans;
bool dp[1010];
int b[7] = {0, 1, 2, 3, 5, 10, 20};
int main () {
	for(int i = 1; i <= 6; i++) {
		cin >> num[i];
	}
	dp[0] = true;
	for(int i = 1; i <= 6; i++) {
		for(int k = 1; k <= num[i]; k++) {
			for(int j = 1000; j >= 0; j--) {
				if(dp[j]) {
					dp[j + b[i]] = true;
				}
			}
		}
		
	}
	for(int i = 1; i <= 1000; i++) {
		if(dp[i]) ans++;
	}
	cout << "Total=" << ans << '\n';
	return 0;
} 

你可能感兴趣的:(洛谷题解,动态规划专题讲解)