【题解】P1441 砝码称重

题目

P1441 砝码称重

思路

状态压缩 + \(dp\)
将不选哪个砝码压成二进制,如一共有 \(8\) 个砝码,不选 \(1,3,4\),二进制数为 \(00001101\)
状态压缩后就可以枚举不选哪个砝码了。
\(dp\) 算在 \(i\) 的情况下能量出多少种。

Code

#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>

int ans, num ,maxx;
int n, m, a[21];
bool f[3001];

int max(int a, int b) { return a > b ? a : b; }

void dp(int x) {//这里是dp计算在x的情况下能量出多少种
	memset(f, 0, sizeof f);
	f[0] = 1;
	int temp = 0, tot = 0;
	for (int i = 1; i <= n; ++i) {
		if (x & (1 << (i - 1))) continue;
		for (int j = tot; j >= 0; --j) {
			if (f[j] && !f[j + a[i]]) {
				f[j + a[i]] = 1;
				++temp;
			}
		}
		tot += a[i];
	}
	ans = max(ans, temp);
}

int main() {
	scanf("%d %d", &n, &m);
	for (int i = 1; i <= n; ++i) scanf("%d", &a[i]);
	for (int i = 0; i < (1 << n); ++i) {//这里是状态压缩枚举不选哪个砝码
		int d = i, cnt = 0;
		while(d) {
			if (d & 1) ++cnt;
			d >>= 1;
		}
		if (cnt == m) dp(i);
	}
	printf("%d\n", ans);
	return 0;
}
posted @ 2020-07-13 11:08  yu__xuan  阅读(163)  评论(0编辑  收藏  举报