EOJ 1082 Easy to AC(枚举+二进制子集法)

二进制枚举子集的技巧详解 全网最详细!细致分析二进制枚举子集,拆解代码详细分析,配有实例,手把手模拟讲解! 阅读详情

题目

题意:判断非负整数 n (n<=1 000 000)能否表示为各不相同的非负数字的阶乘之和,比如9 = 1!+2!+3!

解题思路

由于这些非负数字可以不是相邻的,所以要枚举所有的组合,那么就可以用二进制取子集的方法。

利用二进制的“开关”特性枚举;
具体为:假设给定集合A大小为n,则想象A = {a[0], a[1], …, a[n-1]}的每个元素对应一个开关位(0或1),0表示不出现,1表示出现;当每个元素的开关位的值确定时,就得到一个子集,因此共有2^n-1种情况(全0为空集);
我们利用区间[1, 2^n-1]上的每个整数来对应每个子集,对应方法是:遍历该整数二进制表示的每一位,若该位为1则相应子集中存在对应元素,否则不存在。

在本题中,由于n<=107,而10! = 3628800,所以最多只需要考虑10以内的阶乘。

遍历[1,210−1]中的每一个整数,对每个整数,检测该整数的每个二进制位,若该位为1则表示取其所在位置的阶乘累加。比如,1011表示sum=fac[0]+fac[1]+fac[3]=8.

需要注意的是:

  • 提前打表可以节约后续的计算时间,即将所有满足题意的数先标记出来,判断时直接查询即可。
  • 子集法中的0(空集)在本题属于特殊情况,因为0不能由其它数阶乘得到,但在枚举时中会被标记。

AC代码

#include <iostream>

using namespace std;
const int maxn = 1e7 << 1;

bool judge[maxn]; //打表判断i是否为阶乘之和
int fac[15]; //存放阶乘

void init()
{
    //计算阶乘
    fac[0] = 1;
    for (int i = 1; i <= 10; ++i)
        fac[i] = fac[i-1] * i;
    //打表
    fill(judge, judge+maxn, false);
    int sum = 0;
    for (int i = 0; i < (1<<10); ++i) //二进制子集法,遍历2^10-1个子集
    {
        sum = 0;
        for (int j = 0; j < 10; ++j) //移位检测1出现的位置
            if (i & (1<<j))
                sum += fac[j];
        judge[sum] = true;
    }
    judge[0] = false; //特殊:0不是阶乘之和!
}

int main()
{
    int n, m;
    init();
    while (cin >> n && n >= 0)
    {
        if (judge[n]) cout << "YES" << endl;
        else cout << "NO" << endl;
    }
    return 0;
}
子集枚举的二进制(位运算)方法 #include <bits/stdc++.h> int a[5] = {1, 3, 5, 6, 8}; void print_subset(int n, int s) { for(int i = 0; i < n; i++) { if(s & (1 << i)) printf("%d ", a[i]); } printf("\n"); } int main 阅读详情

相关推荐

子集(二进制序列枚举法)1

示例 1:输出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]示例 2:输出:[[],[0]]解题思路:数组中的每一个数字

二进制枚举子集(总结+应用)

文章目录定义阐明简单的知识铺垫应用举例代码实现例题应用思路如下:题解如下:其它例题 定义阐明 1.什么是子集:子集是一个数学概念:如果集合A的任意一个元素都是集合B的元素,那么集合A称为集合B的子集。符号语言:若∀a∈A,均有a∈B,则A⊆B。(再说简单点就是 :如果B是A的子集,那么无论B是事件内容是什么、情况是什么,A总包含所的 内容、情况,而其中的 一些 内容、情况 正好就是 B里面的内...

做一只熊猫不好吗? 2196

蛋白质组学实战指南 | (八)从数据到洞见:差异蛋白筛选与功能解析全流程

本文系统阐述了蛋白质组学数据分析中,从原始数据质控到差异蛋白筛选与功能解析的全流程。重点介绍了数据质量评估、差异蛋白筛选的统计方法(包括多重检验校正)、功能注释与富集分析,以及蛋白互作网络构建与关键节点识别。最后,为如何将生物信息学洞见转化为实验验证提供了清晰的规划思路,助力研究者完成从数据到生物学知识的闭环。

weixin_29250573的博客 372

二进制的应用——枚举子集

集合是指由一个或多个确定的元素所构成的整体,也可以当作不分顺序的数组 当集合中不包含任何元素时,我们称它为空集 我们一般用大括号及期中若干元素表示一个集合,例如1,3,5{1,3,5}1,3,5表示包含元素1,3,5的一个集合,a,x,abc{a,x,abc}a,x,abc表示包含三个字符串元素的集合 在集合的元素中没有先后顺序,例如集合1,2,3{1,2,3}1,2,3和{3,1,2}是等价的 在集合中,有一些集合间的关系,我们这种送会用到一个关系是子集,我们说集合A是集合B的子集,表示A钟所有元素都在B

AliceK1008的博客 1018

西门子PLC1200与CB1241模块的Modbus RTU从站配置全流程(附串口调试技巧)

本文详细介绍了西门子S7-1200 PLC与CB1241通信模块实现Modbus RTU从站配置的全流程,包括硬件接线规范、TIA Portal工程组态、通信指令编程及串口调试技巧。通过实战案例和常见错误处理方案,帮助工程师快速搭建稳定的工业通信系统,提升自动化设备的互联互通能力。

weixin_29165725的博客 328

NRF24L01模块的5个常见问题及解决方案:从信号干扰到功耗优化

本文深入探讨NRF24L01无线模块在STM32开发中的5大常见问题及解决方案,包括通信距离优化、数据丢失排查、电源噪声抑制、SPI通信故障处理以及低功耗设计。通过代码示例和电路图分析,提供实用的优化策略,帮助开发者提升无线通信的稳定性和效率。

weixin_28256233的博客 226

二进制枚举子集详解

定义 先给出子集的定义:子集是一个数学概念:如果集合A的任意一个元素都是集合B的元素,那么集合A称为集合B的子集。 用途 在写程序的时候,有时候我们可能需要暴力枚举出所有的情况,这时可以考虑通过二进制来枚举子集来尝试解决问题。 解释 假设我们现在有5个小球,上面分别标号了0,1,2,3,4代表这些小球的权值,现在要像你求出这些小球的权值可以组成的所有情况。 我们用二进制的思维来...

riba2534的博客 7106

Auto.js凉了之后,我们该用啥?AutoX.js保姆级环境搭建与第一个脚本实战(2024最新)

本文详细介绍了AutoX.js作为Auto.js替代方案的环境搭建与脚本开发实战指南。从技术生态现状分析到2024最新环境配置,再到编写第一个实用脚本和进阶调试技巧,帮助开发者无缝迁移至AutoX.js平台。特别适合需要手机自动化的JavaScript开发者,涵盖从基础到企业级应用的全套解决方案。

weixin_28737073的博客 391

枚举二进制数的子集

如1011的二进制子集有1011,1010,1001,1000,0011,0010,0001,0000思想是每次对当前最小子元素-1与目标x取与运算。枚举到0为止。

WQhuanm的博客 1240

大语言模型(LLM)在组合优化中的新突破:LLM-LNS与FunSearch性能对比

本文深入探讨了大语言模型(LLM)在组合优化中的创新应用,重点对比了LLM-LNS与FunSearch两种方法的性能差异。研究表明,LLM-LNS在物流路径规划、资源调度等场景中展现出显著优势,其双层自演化架构能有效平衡探索与利用,相比传统方法提升效率约43%。文章还提供了实践选择指南,帮助开发者根据具体需求选用合适的技术方案。

weixin_42526415的博客 406

记一次springboot集成海康威视SDK过程

一开始没有接触过物联网这块,走了很多弯路,后面还是自己一点点摸索出来的。有个项目,需要对海康的门禁设备进行集成,后台统一管理设备,进行设备人脸数据的下发、删除等操作。3.我还接入了门禁设备的事件监听,门禁所有的事件都会上报到后台服务,这块代码有需要的可以找我。在linux系统中,sdk我使用的是绝对路径,把Linux版本的文件放到服务时,Acs文件夹下的 各个Manage都有现成的代码,可以根据自己的需要调用即可。路径也不要有中文,切记!2.sdk的存放路径不要有中文,不然会出现很多奇怪的问题。

huang_xiaoen的博客 2348

枚举子集(二进制的集合 和 普通的集合)

一.二进制的集合 for (int S1 = S; S1; (S1 - 1) & S) S2 = S ^ S1; 其中是的子集,则是的补集. 下面我们证明一下为什么这样枚举是对的. 1.我们先证明这样枚举出来的集合都是的集合: 因为S1 & S,根据位运算的性质可知,S1必然是S的子集,证毕. 2.再证明为什么这样枚举可以枚举到所有的子集: 首先,S是自身的子集.其次是S1 - 1的作用.分情况讨论,如果当前的S1的最后一位是1,-1的作用就是把1变成0,经过&amp

CK1513710764的博客 571

015、架构_配置文件_管理节点(proxymanager.ini)

该配置文件中的参数在后台配置,两种生效方式:*所有参数重启生效。*部分参数可以使用工具dbtool动态生效。动态生效命令为:dbtool-pm-load-config。配置文件“proxymanager.ini”用于设置元数据管理模块的信息。文件路径为“~/etc”。配置文件“proxymanager.ini”是普通的文本文件。默认值proxymanager-alarmconfutf8.txt。配置错误或不配置,PM无法连接MDS,无法服务。获取元数据失败超时处理时间。异常时请求启动对等回滚。

Oracle/MySQL 到 国产信创数据库|迁移 · 调优 · 信创替换 329

回溯题解——子集【LeetCode】二进制枚举法

这是一种非常高效、简洁的生成子集的方式,尤其适用于集合元素较少(如 n ≤ 20)的场景。的二进制表示就是一个子集的“选取方案”,每一位表示该位置元素选不选。位二进制数表示(0 表示不选,1 表示选)。,每个整数的二进制形式唯一表示一个子集。每次生成一个子集使用一个列表(临时变量。个子集,每个最多判断 3 个位置。位运算用于高效判断哪些元素被选中。所以总的空间用于保存输出结果是。的简写方式,表示子集的总数。,就说明这个元素被选入子集。将每一个子集的选取用一个。位是否为1的经典写法。(第0和第2位是1)。

chao_789的博客 650

Python 对接钉钉获取员工上一篇日报或周报内容

摘要:本文介绍使用Python对接钉钉API获取员工日报/周报的方法。首先需创建钉钉应用并开通日志权限,获取员工UserID。通过获取AccessToken进行鉴权,调用topapi/report/list查询日志记录,筛选最新日报/周报后,使用topapi/report/details获取详细内容。需注意权限控制、时间范围筛选和模板匹配等问题。文末提供完整代码示例,并建议扩展自动化触发、数据存储等功能。该方法适用于企业自动化获取员工工作日志的场景。

从技术实践立足,从项目管理方法论延伸思考 808

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

leetcode 78. 子集(二进制枚举详解)c++

⼆进制枚举⼆进制枚举⼆进制枚举:⽤⼀个数⼆进制表⽰中的0/1表⽰两种状态,从⽽达到枚举各种情况。利⽤⼆进制枚举时,会⽤到⼀些位运算的知识。关于⽤⼆进制中的0/1表⽰状态这种⽅法,以后在讨论状态压缩dp中会继续使⽤到。⼆进制枚举的⽅式也可以⽤递归实现,后续在讨论。

weixin_73266891的博客 575

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

二进制枚举子集

二进制枚举子集 定义:用二进制的一位表示集合对应某一元素的选取状态,1表示选取,0表示未选取。 位的逻辑运算符:位运算是对二进制的每一位进行计算,所以每一位只有0或1两种可能。常用的位运算符:与 &amp; 、或 | 、异或 ^ ,运算规则 与运算:两者都为1时,结果即为1,否则为0 。 或运算:两者都为0时,结果即为0,否则为1。 异或运算:是两者同为0或1时,结果即为 0,否则为1 ...

LiuKairui的博客 1318

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

算法 {二进制枚举全组合子集}

1

qq_66485519的博客 534

算法题(125):子集

我们先以给定数据个数为3举例,我们发现当数为8时,二进制的倒数第四位就有1了,说明到7的时候已经完成了数据个数为3所有的遍历。而8就是由1左移3位得到的,7是由8-1得到的。那么此时对于数字0~7的二进制情况,我们发现恰好完成了子集的枚举。首先将需要遍历到的数依次取出,然后根据这些数的不同二进制位数值情况对子集进行数据插入。对于1数字,0索引位置值为1,其他位置值为0,说明这是只选择索引为0的数字的情况。比如对于0数字,0~2的索引位置值都为0,说明这是三个数字都不选的情况。枚举方式:二进制枚举。

2301_79954395的博客 356

二进制法枚举子集

二进制法枚举子集:  n个数有2^n个子集,每个子集对应一个二进数,每位二进制对应一个数。二进制的位权为0表示子集不包含那个数,二进制的位权为1表示子集包含那个数。 案例  2  1  10  7  5 7 4 8 6 7 5  取n=7 二进制 子集 0 0 0 1 1 5

LzyRapX 3942

二进制枚举!

那么当前选择的状态就可以用二进制10101来表示,也就是十进制中的21。例如上面我们在{1,2,3,4,5}中取了1,3,4,二进制为10101,我们枚举的是二进制的十进制形式,也就是21,我们可以把21转化为2、二进制后取出为1的元素,但这很麻烦。很容易看出,我们只需要(1

m0_73870617的博客 327

1863. 找出所有子集的异或总和再求和 01.11(五)

[5,1,6] 的异或总和为 5 XOR 1 XOR 6 = 2。- [1,3] 的异或总和为 1 XOR 3 = 2。- [5,1] 的异或总和为 5 XOR 1 = 4。- [5,6] 的异或总和为 5 XOR 6 = 3。- [1,6] 的异或总和为 1 XOR 6 = 7。每个子集的全部异或总和值之和为 480。- [1] 的异或总和为 1。- [3] 的异或总和为 3。- [5] 的异或总和为 5。- [1] 的异或总和为 1。- [6] 的异或总和为 6。

小小路灯的博客 596

EOJ 1082. Easy to AC

原题链接 思路分析 法一:动态规划 这个题在dfs标签下,但实际上也可以用其他的方法来写。 因为10的阶乘就已经等于3,628,800且大于1,000,000 先将0到9的阶乘直接算出保存在数组a里。因为刚好在刷01背包的问题,所以换种思路来实现。 使用递归的想法:如果我们遍历处于a[i],和为n时,对于a[i]这个数,我们有两种选择,即选和不选,如果选,那么下一个就是要遍历的位置即为i-1...

CC 306

1082. Easy to AC

单点时限: 2.0 sec 内存限制: 256 MB parytchen 最近做了几个很烦的题目,一直没有 AC,所以决定转型做一道简单题目,调节一下心情, 正好遇见一道简单的题目,partychen 准备把它 AC 掉再说。 数学博大精深,当然组成数学的就是一些数字,这些数字也有很多的特点,比如有一些数字它是另外一些各不相同的非负数字的阶乘之和。比如:数字9,9=1!+2!+3!。所以为了研究一...

Cuibaby的博客 305

运用二进制生成集合的所有子集

感谢刘大大; #include #include #include using namespace std; void print_subset(int n,int s){ for(int i=0;i<n;i++) if(s&(1<<i)) printf("%d",i); cout<<endl; } int main(){ int s[4]={0,1,2,3}; for

努力努力再努力 1184
上一篇: EOJ 3302 打印(动态规划)
下一篇: EOJ 3297 铺瓷砖(DFS)
youth.lin
博客等级 码龄12年 41粉丝 116原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值