数学知识(四)(容斥原理、博弈论)

2024-02-22 19:36

本文主要是介绍数学知识(四)(容斥原理、博弈论),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、容斥原理

容斥原理公式

一共加或者减的式子个数

 

(一)利用容斥原理解决求能被质数整除的数的个数

890计算能被整除的数的个数

因为一共有2^n-1种选法,可以用位运算的方式枚举,对于得到的每一种选法,根据存在的数的个数判断前面是1还是-1。枚举到2^n-1的所有二进制数,判断每一位上的数是否是1,

最重要的转变是:将能被各个质数整除的集合看成一个个的集合。根据容斥原理,需要计算各个集合的组合方式的元素个数然后相加。在找组合方式的时候因为一共有2^n-1种,可以用m位的二进制数表示。如何计算一个一个组合的可以整除的个数。一位一位右移&1判断。

#include<bits/stdc++.h>
//890 求能被质数整除的数
using namespace std;
typedef long long LL;
const int N=20;
int n,m;
int p[N];
int main()
{cin>>n>>m;//读入所有的质数for(int i=0;i<m;i++)cin>>p[i];int res=0;//遍历所有二进制数for(int i=1;i<1<<m;i++){int cnt=0;int t=1;//遍历这个二进制数的所有位for(int j=0;j<m;j++){if(i>>j&1){//记录当前选择集合的个数cnt++;//并将集合元素相乘t*=p[j];//如果n一倍的t都装不了就breakif(t>n){t=-1;break;}}}if(t!=-1){if(cnt%2)res+=n/t;else res-=n/t;}}cout<<res<<endl;}

二、博弈论

891 先手是否先获胜

结论:

如果异或值不是0,先手可以拿一堆石子儿让拿之后状态变成必输。

异或不会产生1,只会消除1。

因为异或上x之后会ai一定会变小,也就是这一堆石子儿是可以让棋手拿的。最后剩余ai异或x。整个式子异或之后是0.也就是可以进行一次操作并得到一个对手必败的局面(不管对手怎么去拿异或之后都不为0)。也就是先手先胜利。

先手遇到的总不是0,后手遇到的总是0,最后后手败。

#include<bits/stdc++.h>
//891 Nim游戏
using namespace std;
typedef long long LL;
int main()
{int n;cin>>n;int res=0;while(n--){int x;cin>>x;res^=x;}if(res)puts("Yes");else puts("No");return 0;
}

三、sg函数

mex是某个点的出边指向的所有点的值(不再其中)的最小的自然数。

如果sg不为0,就说明有出边指向0

nim游戏和sg函数含义相似。每个结点的sg函数可以看做一个小石头堆。nim游戏中异或之后如果不等于0,可以找到ai,拿走ai-ai^x。最后得到的状态就是0。在sg中。如果异或之后的值非0,和nim一样,将其变成ai^x。因为 ai^x<ai.所以一定有一个出边指向ai^x成立,并且之后的状态变成0.

#include <cstring>
#include <iostream>
#include <algorithm>
#include <unordered_set>
using namespace std;
const int N = 110, M = 10010;
int n, m;
int s[N], f[M];
int sg(int x)
{if (f[x] != -1) return f[x];unordered_set<int> S;for (int i = 0; i < m; i ++ ){int sum = s[i];if (x >= sum) S.insert(sg(x - sum));}for (int i = 0; ; i ++ )if (!S.count(i))return f[x] = i;
}int main()
{cin >> m;for (int i = 0; i < m; i ++ ) cin >> s[i];cin >> n;memset(f, -1, sizeof f);int res = 0;for (int i = 0; i < n; i ++ ){int x;cin >> x;res ^= sg(x);}if (res) puts("Yes");else puts("No");return 0;
}

这篇关于数学知识(四)(容斥原理、博弈论)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/736270

相关文章

Spring Boot循环依赖原理、解决方案与最佳实践(全解析)

《SpringBoot循环依赖原理、解决方案与最佳实践(全解析)》循环依赖指两个或多个Bean相互直接或间接引用,形成闭环依赖关系,:本文主要介绍SpringBoot循环依赖原理、解决方案与最... 目录一、循环依赖的本质与危害1.1 什么是循环依赖?1.2 核心危害二、Spring的三级缓存机制2.1 三

C#中async await异步关键字用法和异步的底层原理全解析

《C#中asyncawait异步关键字用法和异步的底层原理全解析》:本文主要介绍C#中asyncawait异步关键字用法和异步的底层原理全解析,本文给大家介绍的非常详细,对大家的学习或工作具有一... 目录C#异步编程一、异步编程基础二、异步方法的工作原理三、代码示例四、编译后的底层实现五、总结C#异步编程

Go 语言中的select语句详解及工作原理

《Go语言中的select语句详解及工作原理》在Go语言中,select语句是用于处理多个通道(channel)操作的一种控制结构,它类似于switch语句,本文给大家介绍Go语言中的select语... 目录Go 语言中的 select 是做什么的基本功能语法工作原理示例示例 1:监听多个通道示例 2:带

鸿蒙中@State的原理使用详解(HarmonyOS 5)

《鸿蒙中@State的原理使用详解(HarmonyOS5)》@State是HarmonyOSArkTS框架中用于管理组件状态的核心装饰器,其核心作用是实现数据驱动UI的响应式编程模式,本文给大家介绍... 目录一、@State在鸿蒙中是做什么的?二、@Spythontate的基本原理1. 依赖关系的收集2.

Java编译生成多个.class文件的原理和作用

《Java编译生成多个.class文件的原理和作用》作为一名经验丰富的开发者,在Java项目中执行编译后,可能会发现一个.java源文件有时会产生多个.class文件,从技术实现层面详细剖析这一现象... 目录一、内部类机制与.class文件生成成员内部类(常规内部类)局部内部类(方法内部类)匿名内部类二、

Python中随机休眠技术原理与应用详解

《Python中随机休眠技术原理与应用详解》在编程中,让程序暂停执行特定时间是常见需求,当需要引入不确定性时,随机休眠就成为关键技巧,下面我们就来看看Python中随机休眠技术的具体实现与应用吧... 目录引言一、实现原理与基础方法1.1 核心函数解析1.2 基础实现模板1.3 整数版实现二、典型应用场景2

Java的IO模型、Netty原理解析

《Java的IO模型、Netty原理解析》Java的I/O是以流的方式进行数据输入输出的,Java的类库涉及很多领域的IO内容:标准的输入输出,文件的操作、网络上的数据传输流、字符串流、对象流等,这篇... 目录1.什么是IO2.同步与异步、阻塞与非阻塞3.三种IO模型BIO(blocking I/O)NI

JAVA封装多线程实现的方式及原理

《JAVA封装多线程实现的方式及原理》:本文主要介绍Java中封装多线程的原理和常见方式,通过封装可以简化多线程的使用,提高安全性,并增强代码的可维护性和可扩展性,需要的朋友可以参考下... 目录前言一、封装的目标二、常见的封装方式及原理总结前言在 Java 中,封装多线程的原理主要围绕着将多线程相关的操

kotlin中的模块化结构组件及工作原理

《kotlin中的模块化结构组件及工作原理》本文介绍了Kotlin中模块化结构组件,包括ViewModel、LiveData、Room和Navigation的工作原理和基础使用,本文通过实例代码给大家... 目录ViewModel 工作原理LiveData 工作原理Room 工作原理Navigation 工

Java的volatile和sychronized底层实现原理解析

《Java的volatile和sychronized底层实现原理解析》文章详细介绍了Java中的synchronized和volatile关键字的底层实现原理,包括字节码层面、JVM层面的实现细节,以... 目录1. 概览2. Synchronized2.1 字节码层面2.2 JVM层面2.2.1 ente