luogu P1441状压DP砝码称重

Posted SSL_ZZL

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了luogu P1441状压DP砝码称重相关的知识,希望对你有一定的参考价值。

砝码称重

luogu P1441 砝码称重


题目


输入

3 1
1 2 2

输出

3


解题思路

用二进制枚举出所有的选数方案
然后出现了一个神奇的东西 bitset
然后。出现了一个更加神奇的东西
bitset<>s
s |= s << a[j]
这里是把s的每一位当做当前位的数能不能被拼出来,比如 s[3] = 1 表示 3 可以被拼出来
那么这是多一个 1 的砝码,3 + 1 = 4 等于第3位的一向前移动 1 位,移到第 4 位表示 4 可以被拼出来
再举一个2的例子直观一点


Code

#include <bits/stdc++.h>

using namespace std;

int n, m, ans, a[30], w[1 << 22];
bitset<2010> s;

int lowbit(int x)   //取出 x 的最后一个1(x = 18(10010), lowbit(x) = 10)
	return (x & -x);


int main() 
	scanf("%d %d", &n, &m);
	for(int i = 1; i <= n; i ++) scanf("%d", &a[i]);
	for(int i = 1; i < (1 << n); i ++)   //枚举所有情况
		w[i] = w[i - lowbit(i)] + 1;  //计算有多少个 1(选了多少数)(有点DP?)
		if(w[i] == n - m) 
			s.reset();  //清空
			s[0] = 1;  //初始化,注意 0 不能算作砝码拼出来的
			for(int j = 1; j <= n; j ++)
				if(i & (1 << (j - 1)))  //第 j 个砝码被选了
					s |= s << a[j];
			ans = max(ans, (int)s.count() - 1);
		
	
	printf("%d", ans);

以上是关于luogu P1441状压DP砝码称重的主要内容,如果未能解决你的问题,请参考以下文章

luogu P1441状压DP砝码称重

Luogu P1441 砝码称重(fj省选)

P1441 砝码称重 状压+bitset的组合

P1441 砝码称重(搜索+队列dp)

状压DP砝码称重

状压DP砝码称重