洛谷 P1441 砝码称重 子集枚举+bitset

54 篇文章 0 订阅

https://www.luogu.org/problem/P1441
题目描述
现有n个砝码,重量分别为a1,a2,a3,……,an,在去掉m个砝码后,问最多能称量出多少不同的重量(不包括0)。
请注意,砝码只能放在其中一边。
输入格式
输入文件weight.in的第1行为有两个整数n和m,用空格分隔
第2行有n个正整数a1,a2,a3,……,an,表示每个砝码的重量。
输出格式
输出文件weight.out仅包括1个整数,为最多能称量出的重量数量。
输入输出样例
输入 #1
复制
3 1
1 2 2
输出 #1
复制
3

思路:枚举 [ 0 , 2 n − 1 ] [0,2^{n}-1] [0,2n1] 2 n 2^{n} 2n种状态,若某个状态的二进制表示含有 n − m n-m nm 1 1 1,那么它二进制为 1 1 1的位就是我们要选取的砝码的标号,利用 b i t s e t bitset bitset来计算答案, b i t s e t [ i ] = 1 bitset[i]=1 bitset[i]=1表示用这些砝码可以表示出重量 i i i,初始化需要令 b i t s e t [ 0 ] = 1 bitset[0]=1 bitset[0]=1,那么对于选取的砝码 a [ j ] a[j] a[j],只需要令: b i t s e t = b i t s e t ∣ ( b i t s e t < < a [ j ] ) bitset=bitset|(bitset<<a[j]) bitset=bitset(bitset<<a[j]),那么 b i t s e t bitset bitset 1 1 1的个数就是能表示出来的重量(答案要减去 1 1 1 因为 0 0 0不算在内)。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

int n,m;
int a[25];

int main()
{
    scanf("%d %d",&n,&m);
    for(int i=0;i<n;i++)
        scanf("%d",&a[i]);
    int times=1<<n;
    int ans=0;
    for(int i=0;i<times;i++)
    {
        if(__builtin_popcount(i)==n-m)
        {
            bitset<2005> b;
            b[0]=1;
            for(int j=0;j<n;j++)
                if(i&(1<<j))
                    b|=b<<a[j];
            ans=max(ans,(int)b.count());
        }
    }
    printf("%d\n",ans-1);
    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值