#状压dp#洛谷 1441 ssl 2045 砝码称重

题目

现有 n n n个砝码,重量分别为 a 1 a_1 a1 a 2 a_2 a2 a 3 a_3 a3 ⋯ \cdots a n a_n an,在去掉 m m m个砝码后,问最多能称量出多少不同的重量(不包括0)。


分析

可以用状压dp解决,当枚举的状态二进制下只有 n − m n-m nm个1时,那么统计能称出多少就行了
状态转移方程 a n s = m a x { b i t s e t 计 算 的 1 的 个 数 } ans=max\{bitset计算的1的个数\} ans=max{bitset1}


代码

#include 
#include 
#define rr register
#define max(a,b) (((a)>(b))?(a):(b))
using namespace std;
int n,m,w[20],ans;
signed cnt(int x){//统计二进制下1的个数
	rr int ans=0;
	for (rr int j=0;j<n;++j)
	if (x&(1<<j)) ans++;
	return ans;
}
signed main(){
	scanf("%d%d",&n,&m);
	for (rr int i=0;i<n;++i) scanf("%d",&w[i]);
	for (rr int i=0;i<(1<<n);++i)
	if (cnt(i)==n-m){
		rr bitset<2010>so; so[0]=1;//首先0是可以通过的
		for (rr int j=0;j<n;++j)
		if (i&(1<<j)) so|=so<<w[j];//往左移的按位或值
		ans=max(ans,so.count());
	}
	return !printf("%d",ans-1);//不包括0
}

你可能感兴趣的:(状压dp,洛谷,1441,ssl,2045,砝码称重)