牛客网暑期ACM多校训练营(第七场)- C - Bit Compression(暴力)

本文介绍了一道ACM竞赛题目BitCompression的解决方案。题目要求对于长度为2^n的二进制数,通过&、^、|操作求得最终剩余一个1的所有可能的方法数量。采用递归加记忆化搜索的方式,优化处理过程,达到O(3^n)的时间复杂度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

牛客网暑期ACM多校训练营(第七场)- C - Bit Compression

题意:

一个长度为2^n的二进制数,每次对这个数进行&、^、|三种操作中的一种,每次操作将两个相邻的数进行该操作得到新的二进制数,然后继续向下,求最后剩下一个1有多少种方法。

 整个效率为O(3^n)在最后几步记忆化一下就能过了。

太多步的话要存的状态太多空间会炸,所以适当就好。

 

#include <iostream>
#include <stdio.h>
#include <map>

using namespace std;
typedef long long int LL;

map<LL, LL>mp;
LL dfs(int *s,int sz){
    LL ss = 0;
    if(sz <= 16) {
        for(int i=0;i<sz;i++) ss = ss * 3 + s[i] + 1;
        if(mp.count(ss)) return mp[ss];
    }
    LL ans = 0;
    int *tem = new int[sz/2 + 10];
    int len = sz / 2;
    for(int i=0;i<len;i++) tem[i] = s[i*2] & s[i*2+1];
    ans += dfs(tem, len);
    for(int i=0;i<len;i++) tem[i] = s[i*2] ^ s[i*2+1];
    ans += dfs(tem, len);
    for(int i=0;i<len;i++) tem[i] = s[i*2] | s[i*2+1];
    ans += dfs(tem, len);
    delete [] tem;
    return sz <=16 ? mp[ss] = ans : ans;
}

int main()
{
    mp[2] = 1; mp[1] = 0;
    int n; scanf("%d", &n); getchar();
    int *a = new int [1<<n+10];
    for(int i=(1<<n)-1;i>=0;i--) a[i] = getchar() - '0';
    printf("%lld\n", dfs(a, 1<<n));
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值