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

RAG 赋能客服机器人:多轮对话与精准回复

在人工智能技术飞速发展的今天,客服机器人已成为企业提升服务效率的重要工具。然而,传统客服系统在多轮对话连贯性和精准回复能力上存在明显短板。检索增强生成(Retrieval-Augmented Generation, RAG)技术通过结合大语言模型(LLM)与外部知识库,为解决这一问题提供了创新路径。本文将深入探讨 RAG 在客服机器人中的应用,重点分析其如何实现多轮对话与精准回复,并结合实际案例与技术框架展开讨论。

shuizhudan223的博客 2143

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

集合是指由一个或多个确定的元素所构成的整体,也可以当作不分顺序的数组 当集合中不包含任何元素时,我们称它为空集 我们一般用大括号及期中若干元素表示一个集合,例如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

解密 vn.py 源码:从事件驱动到模块化设计的实战解析

本文深入解析vn.py源码,重点剖析其事件驱动机制与模块化设计。通过事件引擎、处理器字典等核心组件分析,展示如何实现低耦合高内聚的交易系统架构,并结合实战案例说明模块化设计带来的开发效率提升。文章还详细解读了Gateway抽象层、核心数据结构及设计模式应用,为量化交易开发者提供源码级实践指南。

weixin_27427619的博客 250

基于云盾构建等保三级Web安全体系:从合规要求到实战落地

网络安全等级保护(等保)是保障信息系统安全的重要制度,其核心原理是通过分级防护、动态调整的策略,构建纵深防御体系。在技术层面,等保要求覆盖物理环境、通信网络、区域边界、计算环境和安全管理中心等多个层面,旨在通过技术和管理相结合的方式,有效应对网络攻击和数据泄露风险。对于Web应用而言,满足等保三级要求具有极高的技术价值,它不仅是合规的刚性需求,更是提升业务系统整体安全水位、建立用户信任、保障业务连续性的关键工程实践。在云计算时代,利用云原生安全服务(如Web应用防火墙WAF、云安全中心、态势感知等)可以高效

weixin_29324877的博客 308

二进制枚举子集详解

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

riba2534的博客 7106

Apache-Plc4x-Modbus-Tcp学习记录(一)

Apache-Plc4x-Modbus-Tcp学习记录(一)

weixin_45325423的博客 6988

枚举二进制数的子集

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

WQhuanm的博客 1240

基于Matlab的深度学习OFDM系统信号检测

在接收端,我们首先去除循环前缀,然后对接收到的信号进行FFT变换和QAM解调。在通信系统中,正交频分复用(Orthogonal Frequency Division Multiplexing,OFDM)是一种常用的调制技术,它可以将高速数据流分成若干个低速子载波进行传输,提高了信道利用率和抗干扰性能。接下来,我们使用训练好的神经网络对QAM调制后的数据进行检测,得到估计的FFT变换结果。深度学习方法可以通过大量的训练数据来学习信号的特征,并具有一定的适应能力,在某些情况下可能能够获得更好的检测性能。

2301_79325657的博客 296

数据分享|2023年OSM道路数据(全国,分省,分市)

首先这个工作非常有必要的,因为我们正常使用的道路的分类都是基于包括城市快速路、城市主干路、城市次干路这个体系的,大家对于这个分类体系应该更熟悉,但是OSM地图的道路分类又不是完全按这个来的,所以非常有必要重新分类;搞清楚道路类型是我们使用道路数据做很多工作的基础,比如我们在使用道路数据的时候,经常需要预估道路的行车速度,而这个速度一般就是根据道路类型来的,比如高架路的车速肯定就比城市支路快很多!下载分为两种情况,第一种是下载小区域的数据,比如下载一个街区的数据,第二种为下载整个中国范围的。

JData_Engineer的博客 4306

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

一.二进制的集合 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

寄存器与计数器设计(Verilog)

always @(posedge Reset or posedge Clock)//请在括号中补充敏感信号列表。always @(negedge Resetn , posedge Clock)//请在括号中补充敏感信号列表。always @(negedge Resetn,posedge Clock)//请在括号中补充敏感信号列表。//为了便于自动评测,请勿更改n的值。//为了便于自动评测,请勿更改n的值。//为了便于自动评测,请勿更改n的值。//为了便于自动评测,请勿更改n的值。

M_inherit的博客 362

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

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

chao_789的博客 650

【全志V821_FoxPi】6-3 GC2083 MIPI摄像头适配

本文介绍了在全志V821芯片上适配GC2083 MIPI摄像头的方案。GC2083是一款支持1080P@30fps的高性能CMOS图像传感器,采用MIPI CSI-2接口,具有低功耗特性。文章详细列出了传感器的技术参数和工作电压要求,并提供了设备树配置示例,包括CSI接口、ISP处理单元和传感器节点的具体设置。通过快速配置命令one_gc2083_sensor或手动修改设备树即可启用该摄像头模组,适用于IPC等对图像质量有要求的嵌入式应用场景。

第四维度的博客 1928

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

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

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

weixin_73266891的博客 575

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

二进制枚举子集

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

LiuKairui的博客 1318

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

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、付费专栏及课程。

余额充值