状压DP砝码称重
Posted 行码棋
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了状压DP砝码称重相关的知识,希望对你有一定的参考价值。
https://www.luogu.com.cn/problem/P1441
[
1
,
n
]
[1,n]
[1,n]共n
个砝码,可以将这n
个砝码取不取变成一个状态i
,我们枚举这个状态i
,只有当状态i
中的二进制1
的个数为n - m
时,才进行相应的求最大值操作。
求最大值:
建一个bitset,
,第i
位代表数字i
能否被取到,因为砝码只能放在一边,所以砝码之间的重量全部是加法操作,默认第0
位为1
代表重量0
能够被取到
公式
b
=
b
∣
b
<
<
a
[
j
]
b = b | b << a[j]
b=b∣b<<a[j]是按位进行合并的意思,b
中存储了所有可以得到的重量,如果再有一个砝码
a
[
j
]
a[j]
a[j]可以使用,那么左移
a
[
j
]
a[j]
a[j]位得到新的可以得到的重量,然后与旧的可以得到的重量进行或操作,就可以更新总的可以得到的砝码重量
#include<bits/stdc++.h>
using namespace std;
const int N = 25;
int n, m;
int a[N];
int main()
cin >> n >> m;
for(int i = 0; i < n; i++)
cin >> a[i];
int res = 0;
for(int i = 1; i < 1 << n; i++)
if(__builtin_popcount(i) == n - m)
bitset<2010> b;
b[0] = 1;
for(int j = 0; j < n; j++)
if(i & (1 << j))
b = b | (b << a[j]);
res = max(res, int(b.count()));
cout << res - 1 << "\\n";
return 0;
以上是关于状压DP砝码称重的主要内容,如果未能解决你的问题,请参考以下文章