当前位置: 首页 > news >正文

算法基础学习笔记——⑬高斯消元\组合计数\容斥原理

博主:命运之光
专栏:算法基础学习

在这里插入图片描述

目录

✨高斯消元

✨组合计数

🍓通过预处理逆元的方式求组合数:

🍓Lucas定理:

🍓分解质因数法求组合数:


前言:算法学习笔记记录日常分享,需要的看哈O(∩_∩)O,感谢大家的支持!


✨高斯消元

高斯消元(Gaussian Elimination)是一种用于解线性方程组的算法,通过逐步的行变换来将方程组转化为简化的行阶梯形式,从而求解方程组的解。

🍓以下是一个用C语言编写的高斯消元算法的示例代码:

#include <stdio.h>
#define N 3 // 方程个数和未知数个数
void gaussianElimination(float matrix[N][N + 1], float solution[N]) {int i, j, k;float factor;// 前向消元for (i = 0; i < N - 1; i++) {for (k = i + 1; k < N; k++) {factor = matrix[k][i] / matrix[i][i];for (j = i; j < N + 1; j++) {matrix[k][j] -= factor * matrix[i][j];}}}// 回代求解for (i = N - 1; i >= 0; i--) {solution[i] = matrix[i][N];for (j = i + 1; j < N; j++) {solution[i] -= matrix[i][j] * solution[j];}solution[i] /= matrix[i][i];}
}
int main() {float matrix[N][N + 1];float solution[N];int i, j;printf("Enter the augmented matrix:\n");for (i = 0; i < N; i++) {for (j = 0; j < N + 1; j++) {scanf("%f", &matrix[i][j]);}}gaussianElimination(matrix, solution);printf("Solution:\n");for (i = 0; i < N; i++) {printf("x%d = %.2f\n", i + 1, solution[i]);}return 0;
}

在上述代码中,我们定义了gaussianElimination函数来执行高斯消元算法。算法分为两个阶段:前向消元和回代求解。

前向消元阶段通过循环进行逐行消元操作,将方程组转化为行阶梯形式。首先,通过除以主对角线上的元素将当前行的主元素变为1。然后,通过逐行减去当前行的倍数,将当前列下方的元素变为0。

回代求解阶段从最后一行开始,通过回代计算未知数的值。首先,将当前行的右侧常数项赋值给对应的未知数。然后,逐列减去已知未知数的乘积,最后除以当前行的主元素。

在main函数中,我们首先接受用户输入的增广矩阵,其中最后一列为常数项。然后,调用gaussianElimination函数来解方程组,并将结果打印出来。

你可以运行上述代码,根据提示输入增广矩阵,程序将计算并输出方程组的解。


🍓高斯消元 :

// a[N][N]是增广矩阵
int gauss()
{int c, r;for (c = 0, r = 0; c < n; c ++ ){int t = r;for (int i = r; i < n; i ++ ) // 找到绝对值最大的行if (fabs(a[i][c]) > fabs(a[t][c]))t = i;if (fabs(a[t][c]) < eps) continue;for (int i = c; i <= n; i ++ ) swap(a[t][i], a[r][i]); // 将绝对值最大的行换到最顶端for (int i = n; i >= c; i -- ) a[r][i] /= a[r][c]; // 将当前行的首位变成1for (int i = r + 1; i < n; i ++ ) // 用当前行将下面所有的列消成0if (fabs(a[i][c]) > eps)for (int j = n; j >= c; j -- )a[i][j] -= a[r][j] * a[i][c];r ++ ;}if (r < n){for (int i = r; i < n; i ++ )if (fabs(a[i][n]) > eps)return 2; // 无解return 1; // 有无穷多组解}for (int i = n - 1; i >= 0; i -- )for (int j = i + 1; j < n; j ++ )a[i][n] -= a[i][j] * a[j][n];return 0; // 有唯一解
}

✨组合计数

在C语言中,可以使用动态规划来实现组合计数(Combination Counting)。组合计数用于计算从n个元素中选择k个元素的组合数。

🍓以下是一个用C语言编写的组合计数算法的示例代码:

#include <stdio.h>
// 计算组合数C(n, k)
int combinationCount(int n, int k) {int C[n + 1][k + 1];int i, j;// 基本情况for (i = 0; i <= n; i++) {for (j = 0; j <= i && j <= k; j++) {if (j == 0 || j == i)C[i][j] = 1;elseC[i][j] = C[i - 1][j - 1] + C[i - 1][j];}}return C[n][k];
}
int main() {int n, k;printf("Enter the values of n and k: ");scanf("%d %d", &n, &k);int result = combinationCount(n, k);printf("Combination Count: %d\n", result);return 0;
}

在上述代码中,我们定义了一个combinationCount函数来计算组合数C(n, k)。算法使用动态规划的思想,使用一个二维数组C来存储中间结果。

首先,我们处理基本情况,即当k等于0或k等于n时,组合数C(n, k)为1。然后,通过递推关系C(n, k) = C(n-1, k-1) + C(n-1, k),我们填充C数组的其余元素。

在main函数中,我们接受用户输入的n和k的值,并调用combinationCount函数来计算组合数。然后,我们输出计算结果。

你可以运行上述代码,根据提示输入n和k的值,程序将计算并输出组合数C(n, k)的结果。

请注意,上述代码中的组合计数算法使用了动态规划的方法,对于较大的n和k可能会产生较大的中间结果。在实际应用中,可以使用更高效的算法或数学公式来计算组合数。


🍓递推法求组合数:

// c[a][b] 表示从a个苹果中选b个的方案数
for (int i = 0; i < N; i ++ )for (int j = 0; j <= i; j ++ )if (!j) c[i][j] = 1;else c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % mod;

🍓通过预处理逆元的方式求组合数:

首先预处理出所有阶乘取模的余数fact[N],以及所有阶乘取模的逆元infact[N]

如果取模的数是质数,可以用费马小定理求逆元

int qmi(int a, int k, int p) // 快速幂模板
{int res = 1;while (k){if (k & 1) res = (LL)res * a % p;a = (LL)a * a % p;k >>= 1;}return res;
}
// 预处理阶乘的余数和阶乘逆元的余数
fact[0] = infact[0] = 1;
for (int i = 1; i < N; i ++ )
{fact[i] = (LL)fact[i - 1] * i % mod;infact[i] = (LL)infact[i - 1] * qmi(i, mod - 2, mod) % mod;
}

🍓Lucas定理:

若p是质数,则对于任意整数 1 <= m <= n,有:

C(n, m) = C(n % p, m % p) * C(n / p, m / p) (mod p)

int qmi(int a, int k, int p) // 快速幂模板
{int res = 1 % p;while (k){if (k & 1) res = (LL)res * a % p;a = (LL)a * a % p;k >>= 1;}return res;
}
int C(int a, int b, int p) // 通过定理求组合数C(a, b)
{if (a < b) return 0;LL x = 1, y = 1; // x是分子,y是分母for (int i = a, j = 1; j <= b; i --, j ++ ){x = (LL)x * i % p;y = (LL) y * j % p;}return x * (LL)qmi(y, p - 2, p) % p;
}
int lucas(LL a, LL b, int p)
{if (a < p && b < p) return C(a, b, p);return (LL)C(a % p, b % p, p) * lucas(a / p, b / p, p) % p;
}

🍓分解质因数法求组合数:

当我们需要求出组合数的真实值,而非对某个数的余数时,分解质因数的方式比较好用:

1. 筛法求出范围内的所有质数

2. 通过 C(a, b) = a! / b! / (a - b)! 这个公式求出每个质因子的次数。 n! 中p的次数是 n / p + n / p^2 + n / p^3 + ...

3. 用高精度乘法将所有质因子相乘

int primes[N], cnt; // 存储所有质数
int sum[N]; // 存储每个质数的次数
bool st[N]; // 存储每个数是否已被筛掉
void get_primes(int n) // 线性筛法求素数
{for (int i = 2; i <= n; i ++ ){if (!st[i]) primes[cnt ++ ] = i;for (int j = 0; primes[j] <= n / i; j ++ ){st[primes[j] * i] = true;if (i % primes[j] == 0) break;}}
}
int get(int n, int p) // 求n!中的次数
{int res = 0;while (n){res += n / p;n /= p;}return res;
}
vector<int> mul(vector<int> a, int b) // 高精度乘低精度模板
{vector<int> c;int t = 0;for (int i = 0; i < a.size(); i ++ ){t += a[i] * b;c.push_back(t % 10);t /= 10;}while (t){c.push_back(t % 10);t /= 10;}return c;
}
get_primes(a); // 预处理范围内的所有质数
for (int i = 0; i < cnt; i ++ ) // 求每个质因数的次数
{int p = primes[i];sum[i] = get(a, p) - get(b, p) - get(a - b, p);
}
vector<int> res;
res.push_back(1);
for (int i = 0; i < cnt; i ++ ) // 用高精度乘法将所有质因子相乘for (int j = 0; j < sum[i]; j ++ )res = mul(res, primes[i]);

✨容斥原理

在C语言中,可以使用容斥原理(Inclusion-Exclusion Principle)来解决一些计数问题。容斥原理是组合数学中的一个重要原理,用于计算多个集合的并集、交集等情况下的计数问题。

🍓以下是一个用C语言编写的容斥原理算法的示例代码:

#include <stdio.h>// 计算集合交集的大小
int intersectionSize(int set[], int setSize) {int result = set[0];for (int i = 1; i < setSize; i++) {result &= set[i];}return result;
}// 计算集合并集的大小
int unionSize(int set[], int setSize) {int result = set[0];for (int i = 1; i < setSize; i++) {result |= set[i];}return result;
}// 计算容斥原理的应用
int inclusionExclusion(int sets[][3], int numSets, int setSize) {int result = 0;for (int i = 1; i < (1 << numSets); i++) {int sign = (__builtin_popcount(i) % 2 == 1) ? 1 : -1;int tempSet[setSize];for (int j = 0; j < setSize; j++) {tempSet[j] = 0;}for (int j = 0; j < numSets; j++) {if (i & (1 << j)) {for (int k = 0; k < setSize; k++) {tempSet[k] |= sets[j][k];}}}int intersection = intersectionSize(tempSet, setSize);result += sign * intersection;}return result;
}int main() {int sets[3][3] = {{1, 2, 3},{2, 3, 4},{3, 4, 5}};int numSets = 3;int setSize = 3;int result = inclusionExclusion(sets, numSets, setSize);printf("Result: %d\n", result);return 0;
}

在上述代码中,我们定义了三个函数:intersectionSize用于计算集合交集的大小,unionSize用于计算集合并集的大小,inclusionExclusion用于应用容斥原理。

intersectionSize函数通过遍历集合元素并执行按位与操作来计算集合交集的大小。

unionSize函数通过遍历集合元素并执行按位或操作来计算集合并集的大小。

inclusionExclusion函数使用位运算和循环来实现容斥原理的应用。它从空集开始,遍历所有子集,并计算交集的大小。根据子集中元素的数量的奇偶性,确定交集的贡献正负号,并累加到最终结果中。

在main函数中,我们定义了一个包含三个集合的二维数组,并调用inclusionExclusion函数来应用容斥原理计算结果。

你可以运行上述代码,它将输出应用容斥原


相关文章:

算法基础学习笔记——⑬高斯消元\组合计数\容斥原理

✨博主&#xff1a;命运之光 ✨专栏&#xff1a;算法基础学习 目录 ✨高斯消元 ✨组合计数 &#x1f353;通过预处理逆元的方式求组合数: &#x1f353;Lucas定理: &#x1f353;分解质因数法求组合数&#xff1a; 前言&#xff1a;算法学习笔记记录日常分享&#xff0c;需…...

渗透测试辅助工具箱

0x01 说明 渗透测试辅助工具箱 运行条件&#xff1a;jdk8 双击即可运行 反弹shell&#xff0c;命令生成器&#xff0c;自动编码&#xff0c;输入对应IP端口即可&#xff0c;实现一劳永逸&#xff0c;集成一些小工具&#xff0c;辅助渗透&#xff0c;提高效率 输入框说明 L…...

chatgpt赋能python:Python后退命令:如何让你的程序退回到之前的状态

Python后退命令&#xff1a;如何让你的程序退回到之前的状态 Python是一种高级编程语言&#xff0c;因其易读易懂而闻名于世。Python中有很多命令用于编写程序&#xff0c;其中一项重要的命令是后退命令。本文将介绍Python后退命令的使用方法&#xff0c;并为您提供详细的步骤…...

OJ练习第127题——统计范围内的元音字符串数

统计范围内的元音字符串数 力扣链接&#xff1a;2559. 统计范围内的元音字符串数 题目描述 给你一个下标从 0 开始的字符串数组 words 以及一个二维整数数组 queries 。 每个查询 queries[i] [li, ri] 会要求我们统计在 words 中下标在 li 到 ri 范围内&#xff08;包含 这…...

图片优化: CssSprites与Base64编码

文章目录 1 css sprites1.1 CSS Sprites是什么1.2 为什么需要css sprites1.3 优势1.4 使用原理1.5 DEMO 2 图片Base64编码 1 css sprites 1.1 CSS Sprites是什么 CSS Sprites是一种网页图片应用处理方式。 又被解释为&#xff1a; CSS精灵CSS图像拼合CSS贴图定位CSS图片精灵…...

JavaScript中的Map、WeakMap和Object的区别

Map Map是一种新的数据结构&#xff0c;它允许使用任何数据类型&#xff08;包括对象和基本数据类型&#xff09;作为键。 Map的一些特性包括&#xff1a; 保持键的插入顺序&#xff1a;当遍历Map时&#xff0c;键值对会按照插入顺序返回。键可以是任意类型&#xff1a;与Obj…...

华为OD机试之打印机队列(Java源码)

打印机队列 题目描述 有5台打印机打印文件&#xff0c;每台打印机有自己的待打印队列。 因为打印的文件内容有轻重缓急之分&#xff0c;所以队列中的文件有1~10不同的代先级&#xff0c;其中 数字越大优先级越高 打印机会从自己的待打印队列中选择优先级最高的文件来打印。 如…...

分享一个国内免费的ChatGPT网站,手机电脑通用,免费无限制,支持AI绘画

背景 ChatGPT作为一种基于人工智能技术的自然语言处理工具&#xff0c;近期的热度直接沸腾&#x1f30b;。 作为一个AI爱好者&#xff0c;翻遍了各大基于ChatGPT的网站&#xff0c;终于找到一个免费&#xff01;免登陆&#xff01;手机电脑通用&#xff01;国内可直接对话的C…...

【面向对象编程1】——类和对象——如桃花来

目录索引 面向过程和面向对象的区别&#xff1a;面向过程&#xff1a;面向对象&#xff1a;总结&#xff1a; 类和对象&#xff1a;定义类&#xff1a;语法&#xff1a; 创建对象&#xff1a;实例演示&#xff1a; 魔法方法&#xff1a;__init __方法&#xff1a;__ del __方法…...

chat聊天系统消息消费时遇到的问题及优化思路(二)

1、前言 考虑下面几个条件下如何提升kafka的消费速度 消息要求严格有序&#xff0c;如chat聊天消息业务处理速度慢&#xff0c;如处理一条数据需要100ms分片不合理&#xff0c;如有的分区很闲&#xff0c;有的分区消息数量积压 2、解决方案 1、顺序问题 关于消息消费时存在…...

js正则中的match()

在前端开发中&#xff0c;正则表达式是一大利器。所以我们这次就来讨论下match()方法。 match本身是JavaScript语言中字符串对象的一个方法&#xff0c;该方法的签名是 match([string] | [RegExp]) 它的参数既可以是一个字符串&#xff0c;也可以是一个正则表达式。该方法绝…...

Apache 配置和应用

目录 构建虚拟 Web 主机 Options指令解释 Options指令常用选项 AllowOverride指令解释&#xff1a; 地址限制策略&#xff1a; httpd服务支持的虚拟主机类型包括以下三种: 基于域名的虚拟主机 1&#xff0e;为虚拟主机提供域名解析 2.为虚拟主机准备网页文档 3.添加虚拟…...

实现PyTorch/ONNX自定义节点操作的TensorRT部署

参考一 下面是基本步骤&#xff1a; 加载训练好的bev transformer网络权重参数&#xff1a; import torch from model import Modelmodel Model() model.load_state_dict(torch.load("path/to/weights"))定义新的自定义操作&#xff1a; import torch from torc…...

Shamir 秘密共享、GMW和BGW方案

一、Shamir秘密共享 Shamir秘密共享方案是一种将秘密拆分成多份并分配给多个参与者保存&#xff0c;只有在满足特定条件下才能恢复原始秘密的密码学方案。它具有良好的容错性、加法同态性和无条件安全性等特点。 具体地&#xff0c;Shamir秘密共享方案可以概括为以下步骤&…...

Day56【动态规划】583.两个字符串的删除操作、72.编辑距离

583.两个字符串的删除操作 力扣题目链接/文章讲解 视频讲解 1、确定 dp 数组下标及值含义 dp[i][j]&#xff1a;以下标 i 为结尾的字符串 word1&#xff0c;和以下标 j 为结尾的字符串 word2&#xff0c;想要达到相等&#xff0c;所需要删除元素的最少次数为 dp[i][j] 2、…...

Arnold图像置乱的MATLAB实现

这件事情的起因是这样的&#xff0c;我需要研究一下各种图像置乱的算法。然后在知乎上找到了一篇关于Arnold变化的文章&#xff0c;但是呢&#xff0c;这个人实际上是卖资料&#xff0c;代做大作业的。详细的代码根部不给你&#xff0c;则给我气坏了&#xff0c;必须要手动实现…...

ASP.NET Core

1. 入口文件 一个应用程序总有一个入口文件&#xff0c;是应用启动代码开始执行的地方&#xff0c;这里往往也会涉及到应用的各种配置。当我们接触到一个新框架的时候&#xff0c;可以从入口文件入手&#xff0c;了解入口文件&#xff0c;能够帮助我们更好地理解应用的相关配置…...

javascript基础二十二:举例说明你对尾递归的理解,有哪些应用场景

一、递归 递归&#xff08;英语&#xff1a;Recursion&#xff09; 在数学与计算机科学中&#xff0c;是指在函数的定义中使用函数自身的方法 在函数内部&#xff0c;可以调用其他函数。如果一个函数在内部调用自身本身&#xff0c;这个函数就是递归函数 其核心思想是把一个大型…...

hive中如何计算字符串中表达式

比如 select 1(2-3)(-4.1-3.1)-(4-3)-(-3.34.3)-1 col ,1(2-3)(-4.1-3.1)-(4-3)-(-3.34.3)-1 result \ 现在的需求式 给你一个字符串如上述col 你要算出result。 前提式 只有和-的运算&#xff0c;而且只有嵌套一次 -(4-3)没有 -(-4(3-(31)))嵌套多次。 第一步我们需要将运…...

如何将maven项目改为springboot项目?

将 Maven 项目转换为 Spring Boot 项目需要进行以下步骤&#xff1a; 1. 在 Maven 项目中添加 Spring Boot 的依赖。可以通过在 pom.xml 文件中添加以下依赖来实现&#xff1a; <dependency> <groupId>org.springframework.boot</groupId> <artifactId>…...

黑马Mybatis

Mybatis 表现层&#xff1a;页面展示 业务层&#xff1a;逻辑处理 持久层&#xff1a;持久数据化保存 在这里插入图片描述 Mybatis快速入门 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/6501c2109c4442118ceb6014725e48e4.png //logback.xml <?xml ver…...

.Net框架,除了EF还有很多很多......

文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...

Debian系统简介

目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版&#xff…...

DAY 47

三、通道注意力 3.1 通道注意力的定义 # 新增&#xff1a;通道注意力模块&#xff08;SE模块&#xff09; class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...

相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)

【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...

如何理解 IP 数据报中的 TTL?

目录 前言理解 前言 面试灵魂一问&#xff1a;说说对 IP 数据报中 TTL 的理解&#xff1f;我们都知道&#xff0c;IP 数据报由首部和数据两部分组成&#xff0c;首部又分为两部分&#xff1a;固定部分和可变部分&#xff0c;共占 20 字节&#xff0c;而即将讨论的 TTL 就位于首…...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2

每日一言 今天的每一份坚持&#xff0c;都是在为未来积攒底气。 案例&#xff1a;OLED显示一个A 这边观察到一个点&#xff0c;怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 &#xff1a; 如果代码里信号切换太快&#xff08;比如 SDA 刚变&#xff0c;SCL 立刻变&#…...

云原生玩法三问:构建自定义开发环境

云原生玩法三问&#xff1a;构建自定义开发环境 引言 临时运维一个古董项目&#xff0c;无文档&#xff0c;无环境&#xff0c;无交接人&#xff0c;俗称三无。 运行设备的环境老&#xff0c;本地环境版本高&#xff0c;ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...

打手机检测算法AI智能分析网关V4守护公共/工业/医疗等多场景安全应用

一、方案背景​ 在现代生产与生活场景中&#xff0c;如工厂高危作业区、医院手术室、公共场景等&#xff0c;人员违规打手机的行为潜藏着巨大风险。传统依靠人工巡查的监管方式&#xff0c;存在效率低、覆盖面不足、判断主观性强等问题&#xff0c;难以满足对人员打手机行为精…...

Spring AI Chat Memory 实战指南:Local 与 JDBC 存储集成

一个面向 Java 开发者的 Sring-Ai 示例工程项目&#xff0c;该项目是一个 Spring AI 快速入门的样例工程项目&#xff0c;旨在通过一些小的案例展示 Spring AI 框架的核心功能和使用方法。 项目采用模块化设计&#xff0c;每个模块都专注于特定的功能领域&#xff0c;便于学习和…...