luogu P1441状压DP砝码称重
Posted SSL_ZZL
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了luogu P1441状压DP砝码称重相关的知识,希望对你有一定的参考价值。
砝码称重
题目
输入
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砝码称重的主要内容,如果未能解决你的问题,请参考以下文章