程序设计实践练习3 前置知识

本文介绍了程序设计实践中的关键知识点,包括图论中的深度优先搜索、广度优先搜索及Dijkstra最短路径算法,以及动态规划中的背包问题和记忆化搜索。此外,还涵盖了位运算、组合数、最大公约数和快速幂等数学基础,以及数据结构、算法和数学在竞赛中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

程序设计实践练习3 前置知识

图论部分
1. 图的存储 图的存储 - OI Wiki (oi-wiki.org) ——数据结构
2. dfs 深度优先搜索 DFS(图论) - OI Wiki (oi-wiki.org) ——数据结构
3. bfs 广度有效搜索 BFS(图论) - OI Wiki (oi-wiki.org) ——数据结构
4. 单源最短路,比较重要的是dijkstra 最短路 - OI Wiki (oi-wiki.org) ——离散数学

两个版本,暴力实现复杂度 O ( n 2 ) O(n^2) O(n2),不赘述

堆(优先队列)版本:

struct node
{
    int v,w;
};
vector<node> son[1003]; // 存储方式


int dij(int S,int T)
{
    priority_queue<pair<int,int> > q; // 优先队列,默认大根堆,即第一关键字大的在前面
    for (int i = 1; i <= n; ++i)
        dis[i] = 1e8;
    dis[S] = 0;
    q.push({0, S});
    while (!q.empty())
    {
        int u = q.top().second;
        int d = -q.top().first;
        q.pop();
        if (u == T) return dis[T];
        if (d > dis[u]) continue;
        for (auto t : son[u]) // son 是 u 点的子节点列表
        {
            int v = t.v; // 子节点
            int w = t.w; // 边权,与具体存储方式有关
            if (dis[v] > dis[u] + w)
            {
                dis[v] = dis[u] + w;
                q.push({-dis[v], v}); // 由于要求最短路,把所有边权置为负数,(最小的就变成最大了)
            }
        }
    }
    return dis[T];
}
动态规划

只会考一般的简单线性 d p dp dp,通常是背包问题,或者是极值、计数问题。

基础 动态规划基础 - OI Wiki (oi-wiki.org)

背包参考 背包九讲

记忆化搜索 记忆化搜索 - OI Wiki (oi-wiki.org)

罗勇军 DP概述和常见DP面试题 --算法竞赛专题解析

C++ stl

STL 竞赛向快速入门 · 语雀 (yuque.com)

数学
位运算:
  1. a ⊗ b = c a \otimes b = c ab=c 等价于 a ⊗ c = b a \otimes c = b ac=b,两者异或等于第三者

  2. a < < n = a ∗ 2 n a << n = a * 2 ^ n a<<n=a2n a > > n = ⌊ a 2 n ⌋ a >> n = \lfloor \frac {a}{2 ^n} \rfloor a>>n=2na

  3. a + b = 2 ( a & b ) + ( a ⊗ b ) a + b = 2 (a \& b) + (a \otimes b) a+b=2(a&b)+(ab) 不大可能考

  4. 位运算 - OI Wiki (oi-wiki.org) 其他性质

组合数
  1. 杨辉三角打表 f[0][0] = 1, f[i][j] = f[i-1][j] + f[i-1][j-1]

  2. 组合数公式:
    ( n m ) = n ! ( n − m ) ! m ! {n \choose m} = \frac {n!}{(n - m)!m!} (mn)=(nm)!m!n!

一般比较大的组合数,都涉及到逆元计算,不太可能考

const int MOD = 1e9 + 7;  //模数
const int lim = 2e6 + 10; // 组合数最大限度

int fc[lim], rfc[lim];
// fc 代表阶乘
// rfc 代表阶乘的逆元
int qp(int x,int p = MOD - 2) // 快速幂
{
	int res = 1;
	while (p)
	{
		if (p & 1) res = 1ll * res * x % MOD;
		p >>= 1;
		x = 1ll * x * x % MOD;
	}
	return res;
}

void init() // 计算阶乘和阶乘的逆元
{
	fc[0] = 1;
	for (int i = 1; i < lim; ++i)
		fc[i] = 1ll * fc[i - 1] * i % MOD;
	rfc[lim - 1] = qp(fc[lim - 1]);
	for (int i = lim - 1; i > 0; --i)
		rfc[i - 1] = 1ll * rfc[i] * i % MOD;
}

int C(int n,int m) // 组合
{
	if (n < 0 || m > n || m < 0) return 0;
	return 1ll * fc[n] * rfc[m] % MOD * rfc[n - m] % MOD;
}

int A(int n,int m) // 排列
{
	if (m > n || n < 0) return 0;
	return 1ll * fc[n] * rfc[n - m] % MOD;
}

最大公约数
int gcd(int a,int b)
{
    if (b == 0) return a;
    else return gcd(b, a % b);
}

或者直接调用 __gcd(a,b),在库 algorithm

快速幂

快速幂 - OI Wiki (oi-wiki.org)

int qp(int x,int p) // 快速幂
{
	int res = 1;
	while (p)
	{
		if (p & 1) res = 1ll * res * x % MOD;
		p >>= 1;
		x = 1ll * x * x % MOD;
	}
	return res;
}
// 一般都要取模
其他基础知识

算法基础简介 - OI Wiki (oi-wiki.org)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值