算法学习15:数论(高斯消元,组合数,卡特兰数)

算法学习15:数论(高斯消元,组合数,卡特兰数)


文章目录

  • 算法学习15:数论(高斯消元,组合数,卡特兰数)
  • 前言
  • 一、高斯消元
    • 1.输入一个包含n个方程,n个未知数的线性方程组,求解这个方程组。
  • 二、组合数:
    • 求组合数1:1<n<10000,1<b<=a<2000(递推)
    • 组合数2:1<n<10000 1<b<=a<10^5(递推)
    • (3)1<n<20 1<b<=a<10^18 1<p<10^5, 特点:a,b的范围特别大,卢卡斯定理(lucas)
    • (4)1<b<=a<5000, 特点:只用算一组,但是结果特别大,要使用高精度计算
  • 三、卡特兰数:求有几种方案。
  • 总结


前言

在这里插入图片描述


提示:以下是本篇文章正文内容:

一、高斯消元

1.输入一个包含n个方程,n个未知数的线性方程组,求解这个方程组。


在这里插入图片描述


初等行列变换(线性代数)(最后得到一个行阶梯)
(原理)
1.把某一行乘以一个非零的数
2.交换某2行
3.把某行的若干倍加到另一行上去


(步骤实现) 枚举每一列:
1.找到每一列绝对值最大的一行
2.将该行移到最上面(性质2)
3.将该行的第一个数变为1(性质1)
4.将下面所有行的第c列都变成0(性质3)



在这里插入图片描述



在这里插入图片描述


输入一个包含n个方程,n个未知数的线性方程组。
求解这个方程组。
方程的解有三种可能:
1.有唯一解:输出n行,对应n个未知数的解
2.有无穷多解:infinite group solutions
3.无解:no sulution


#include <iostream>
#include <algorithm>
#include <cmath>

using namespace std;

const int N = 110;
const int eps = 1e-6;// 与0做判断用
// 0在计算机中存储可能是0.000000001(不用数有几个0,随便输入的)
// < eps表示为0, >eps表示不为0. 

int n;
double a[N][N];// 系数矩阵 + 常数项 

// 高斯消元 
int gauss()
{
	int c, r;// 列,行 
	for(c = 0, r = 0; c < n; c ++)
	{
		// 找到每一列绝对值最大的一行
		// fabs:浮点数的绝对值 
		int t = r;
		for(int i = r; i < n; i ++)
			if(fabs(a[i][c]) > fabs(a[t][c]))
			 	t = i;
				 
		// fabs(a[t][c]) == 0 
		// 这一列所有元素都为0,直接跳过 
		if(fabs(a[t][c]) < eps) continue;
		
		// 将该行移到最上面(性质2)
		// 将该行的第一个数变为1(性质1)
		// 将下面所有行的第c列都变成0(性质3)
		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];
		for(int i = r + 1; i < n; i ++) 
			if(fabs(a[i][c]) > eps)// 不为0 
				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;// 唯一解 
 } 

int main()
{
	cin >> n;
	for(int i = 0; i < n; i ++)
		// 列要多1,常数项矩阵 
		for(int j = 0; j < n + 1; j ++)
			cin >> a[i][j];
	
	int t = gauss();
		
	//0:唯一解, 1:无穷多解, 2:无解 
	if(t == 0)
	{
		// 第n+1类存储的就是未知数的解 
		for(int i = 0; i < n; i ++) 
			printf("%.2lf\n", a[i][n]);
	 }	 
	 else if(t == 1) puts("Infinite group solutions");
	 else puts("No solution");
	
	return 0;
}

在这里插入图片描述

二、组合数:

(1)给定n组询问,每组给定两个整数a,b,求Cab(从a个样品取出b个样品)mod(10^9 + 7)的值

求组合数1:1<n<10000,1<b<=a<2000(递推)


在这里插入图片描述



#include <iostream>
#include <algorithm>

using namespace std;

const int N = 2000 + 10, mod = 1e9 + 7;

int c[N][N];// 存储预处理的结果,就是组合数的值

void init()
{
	for(int i = 0; i < N; i ++)
		for(int j = 0; j <= i; j ++)// 下三角 
			if(!j) c[i][j] = 1;// j = 0时,值为1 
			// 公式 
			else c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % mod;
 } 
 
 int main()
 {
 	init();
 	
 	int n;
 	scanf("%d", &n);
 	while(n --) 
 	{
 		int a, b;
 		scanf("%d%d", &a, &b);
 		printf("%d\n", c[a][b]);
	 }
 	
 	return 0;
 }


在这里插入图片描述



组合数2:1<n<10000 1<b<=a<10^5(递推)

在这里插入图片描述
在这里插入图片描述



#include <iostream>
#include <algorithm>

using namespace std;

typedef long long LL; 
const int N = 1e5 + 10, mod = 1e9 + 7;

int fact[N], infact[N];

// 计算:a^k % p 
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;
}

 int main()
 {
 	fact[0] = infact[0] = 1;// 0! == 1
 	for(int i = 1; i < N; i ++)
 	{
 		fact[i] = (LL)fact[i - 1] * i % mod;
 		// qmi(i, mod - 2, mod):i % mod 的逆元 
 		infact[i] = (LL)infact[i - 1] * qmi(i, mod - 2, mod) % mod;
	 }
 	
 	int n;
 	scanf("%d", &n);
 	while(n --) 
 	{
 		int a, b;
 		scanf("%d%d", &a, &b);
 		// 除法 转换为逆元 
 		printf("%d\n", (LL)fact[a] * infact[b] % mod * infact[a - b] % mod);
	 }
 	
 	return 0;
 }

在这里插入图片描述



(3)1<n<20 1<b<=a<10^18 1<p<10^5, 特点:a,b的范围特别大,卢卡斯定理(lucas)



在这里插入图片描述


#include <iostream>
#include <algorithm>

using namespace std;

typedef long long LL;

int p;

// 快速幂 
int qmi(int a, int k)
{
	int res = 1;
	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 res = 1;
	// 使用最原始的定义: 
	for(int i = 1, j = a; i <= b; i ++, j --)
	{
		res = (LL)res * j % p;// 分子 
		res = (LL)res * qmi(i, p - 2) % p;// 分母-->逆元 
	}
	return res;
 } 

// 卢卡斯定理 
// 注意1:a,b的输入值可能比较大 
int lucas(LL a, LL b)
{
	if(a < p && b < p) return C(a, b);
	// 可能商还是比较大 
	return (LL)C(a % p, b  % p) * lucas(a / p, b / p);
}

 
 int main()
 {
 	int n;
	 cin >> n;
	 while(n --) 
 	{
 		LL a, b;
 		cin >> a >> b >> p;
 		cout << lucas(a, b) << endl;
	 }
	 return 0;
 }

在这里插入图片描述



(4)1<b<=a<5000, 特点:只用算一组,但是结果特别大,要使用高精度计算



在这里插入图片描述


// 开启O2优化 
// #pragma GCC optimize(2)

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

typedef long long LL;

const int N = 5000 + 10;
int primes[N], cnt;// primes:存储1-a的质数 , 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;
		 }
	 }
 }
 
 // p出现了几次 
 int get(int n, int p)
 {
 	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;
 }
 
 int main()
 {
 	int a, b;
 	cin >> a >> b;
 	
 	// 1.筛素数 
 	// 把1 - 5000 内的素数筛出来 
 	get_primes(a);
 	
 	// 质因数:24 = 2 * 2 * 2 * 3 
 	// 2.求每一个质数出现的次数 
 	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]);
 			
 	for(int i = res.size() - 1; i >= 0; i --) printf("%d", res[i]);
 	puts("");
 	
 	return 0;
 }

在这里插入图片描述


三、卡特兰数:求有几种方案。


在这里插入图片描述



在这里插入图片描述



在这里插入图片描述



在这里插入图片描述



在这里插入图片描述


#include <iostream>
#include <algorithm>

using namespace std;

typedef long long LL;

const int mod = 1e9 + 7;

// 快速幂:求逆元 
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;
 } 
 
 int main()
 {
 	int n;
 	cin >> n;
 	
 	int a = 2 * n, b = n;
 	int res = 1;
 	
 	// 使用求组合数“最原始的公式” 
 	for(int i = a; i > a - b; i --) res = (LL)res * i % mod;
 	for(int i = 1; i <=b; i ++) res = (LL)res * qmi(i, mod - 2, mod) % mod;
 	
 	// 除法,变为逆元 
 	res = (LL)res * qmi(n + 1, mod - 2, mod) % mod;
 	
 	cout << res << endl;
 	return 0;
 }

在这里插入图片描述

总结

提示:这里对文章进行总结:

💕💕💕

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/504342.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

用vscode仿制小米官网

html内容: <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title><link rel&quo…

Intellij IDEA 类注释模板设置

1、配置全局USER 在此配置全局USER&#xff0c;用于填充自动生成的注释中的作者author属性。 注释模板中的user参数是默认是获取系统的用户&#xff08;当然注释作者也可以直接写固定值&#xff09;&#xff0c;如果不想和系统用户用同一个信息&#xff0c;可以在IDEA中进行配…

查生意平台联动SFE上海连锁加盟展,呈现口碑招商盛宴

随着中国广告市场规模突破1251亿美元大关&#xff0c;连锁经营企业在其中的营销投放愈发凸显其重要性。查生意&#xff08;www.chasyi.com&#xff09;&#xff0c;作为国内领先的一站式连锁经营口碑评分查询服务平台&#xff0c;携手SFE上海连锁加盟展览会成功举办了一场严选品…

分布式架构商城系统的设计与实现|SpringCloud+ Mysql+Java+ B/S结构(可运行源码+数据库+设计文档)

本项目包含可运行源码数据库LW&#xff0c;文末可获取本项目的所有资料。 推荐阅读100套最新项目持续更新中..... 2024年计算机毕业论文&#xff08;设计&#xff09;学生选题参考合集推荐收藏&#xff08;包含Springboot、jsp、ssmvue等技术项目合集&#xff09; 目录 1. …

C++格式化输入和输出

格式化输入与输出 除了条件状态外&#xff0c;每个iostream对象还维护一个格式状态来控制IO如何格式化的细节。 格式状态控制格式化的某些方面&#xff0c;如整型值是几进制、浮点值的精度、一个输出元素的宽度等。 标准库定义了一组操纵符来修改流的格式状态。 一个操纵符…

Vue3+.NET6前后端分离式管理后台实战(十)

1&#xff0c;Vue3.NET6前后端分离式管理后台实战&#xff08;十&#xff09;已经在订阅号发布有兴趣的可以关注一下&#xff01; 感兴趣请关注订阅号谢谢&#xff01; 代码已经上传gitee

树莓派串口读取陀螺仪ky9250(mpu9250)数据

9轴姿态角度传感器&#xff0c;其中ky9250陀螺仪由于自带卡尔曼动态滤波算法方便用户使用。ky9250陀螺仪基本可以在各个平台上进行数据的读取&#xff08;如stm32\arduino\C#\Matlab\树莓\Unity3d\python\ROS\英飞凌\Nvidia jetson linux 等&#xff09; 1、树莓派和ky9250的接…

储能系统--BMS系统中的高压BUCK电路

一、Buck关键器件介绍 1、芯片选型 控制方式分类 优势缺点同步 1&#xff1a;效率高 2&#xff1a;MOS压降低 1&#xff1a;成本高 2&#xff1a;下官驱动复杂 异步 1&#xff1a;成本便宜 2&#xff1a;适合较高的输出电压 1&#xff1a;效率低 按照隔离方式分类 隔离电源…

会员制医疗预约服务管理信息系统的设计与实现|Springboot+ Mysql+Java+ B/S结构(可运行源码+数据库+设计文档)

本项目包含可运行源码数据库LW&#xff0c;文末可获取本项目的所有资料。 推荐阅读100套最新项目持续更新中..... 2024年计算机毕业论文&#xff08;设计&#xff09;学生选题参考合集推荐收藏&#xff08;包含Springboot、jsp、ssmvue等技术项目合集&#xff09; 1. 系统功能…

基于Givens旋转完成QR分解进而求解实矩阵的逆矩阵

基于Givens旋转完成QR分解进而求解实矩阵的逆矩阵 目录 前言 一、Givens旋转简介 二、Givens旋转解释 三、Givens旋转进行QR分解 四、Givens旋转进行QR分解数值计算例子 五、求逆矩阵 六、MATLAB仿真 七、参考资料 总结 前言 在进行QR分解时&#xff0c;HouseHolder变换…

python基础——文件操作【文件编码、文件的打开与关闭操作、文件读写操作】

&#x1f4dd;前言&#xff1a; 这篇文章主要讲解一下python中对于文件的基础操作&#xff1a; 1&#xff0c;文件编码 2&#xff0c;文件的打开与关闭操作 3&#xff0c;文件读写操作 &#x1f3ac;个人简介&#xff1a;努力学习ing &#x1f4cb;个人专栏&#xff1a;C语言入…

docker centos7在线安装Nginx

目录 1.在线安装Nginx2.配置开机启动 1.在线安装Nginx # 安装Nginx yum install epel-release yum install nginx2.配置开机启动 # 启动Nginx systemctl start nginx # 开机自启 systemctl enable nginx一般docker内的centos7安装Nginx的目录结构是&#xff1a; /etc/nginx为…

蓝桥杯第七届大学B组详解

目录 1.煤球数量&#xff1b; 2.生日蜡烛&#xff1b; 3.凑算式 4.方格填数 5.四平方和 6.交换瓶子 7.最大比例 1.煤球数量 题目解析&#xff1a;可以根据题目的意思&#xff0c;找到规律。 1 *- 1个 2 *** 3个 3 ****** 6个 4 ********** 10个 不难发现 第…

教培机构办公管理系统B端实战项目作品集Figma源文件

这是一套教培机构办公管理系统设计复盘作品集&#xff0c;都提供分层源文件 交付文件&#xff1a;设计复盘作品集源文件作品集里面的B端设计项目包装样机字体文件 交付格式&#xff1a;figma 作品集文件页数&#xff1a;19页 B端项目文件页数&#xff1a;15页 B端项目源文…

linux文件系统:VFS

文章目录 vfs1 super_block2 dentry2.1 dentry树2.2 dentry的cache2.3 挂载 3 inode4 文件file5 vfs各结构体的关系 vfs Linux内核通过虚拟文件系统&#xff08;Virtual File System&#xff0c;VFS&#xff09;管理文件系统 VFS为所有的文件系统提供了统一的接口&#xff0c…

算法沉淀——动态规划篇(子数组系列问题(上))

算法沉淀——动态规划篇&#xff08;子数组系列问题&#xff08;上&#xff09;&#xff09; 前言一、最大子数组和二、环形子数组的最大和三、乘积最大子数组四、乘积为正数的最长子数组长度 前言 几乎所有的动态规划问题大致可分为以下5个步骤&#xff0c;后续所有问题分析都…

Available platform plugins are: linuxfb, minimal, offscreen, vnc.

说明&#xff1a; buildroots根文件中已经移植好了QT的库&#xff0c;但是运行QT交叉编译之后的可执行文件报错&#xff1a; qt.qpa.plugin: Could not find the Qt platform plugin "eglfs" in "" This application failed to start because no Qt platf…

P4995 跳跳!(贪心)

多么痛的领悟&#xff01;大数据要开long long&#xff01;&#xff01;&#xff01;简单longlong就AC&#xff01; 代码1&#xff1a; #include<algorithm> #include<iostream> #include<cstring> #include<queue> #include<cmath> using name…

哪种排序算法在不同情况下性能最好?

哪种排序算法在不同情况下性能最好&#xff1f;&#x1f50d;&#x1f4ca; 哪种排序算法在不同情况下性能最好&#xff1f;&#x1f50d;&#x1f4ca;&#x1f4dd; 摘要&#x1f680; 引言&#x1f4cb; 正文内容&#xff08;详细介绍&#xff09;冒泡排序快速排序&#x1f…

基于ssm旅游资源网站(java项目+文档+源码)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于ssm的旅游资源网站。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 项目简介&#xff1a; 旅游资源网站的主要使用者分为管理…