蓝桥杯必考算法解析及真题实战【2025年最新版】
一、动态规划(DP)高频考点
动态规划是蓝桥杯中最常考的算法之一,常见于最优解问题和组合计数问题。
1.1 经典题型:包子凑数
题目描述:给定N种蒸笼容量,判断无法凑出的包子数量的总数(若无限多个则输出INF)。
解题思路:
- 数论基础:若所有容量的最大公约数不为1,则存在无限个无法凑出的数;
- 背包DP:用布尔数组
dp[i]
记录能否凑出i个包子,通过状态转移dp[j + a] = dp[j] | dp[j + a]
更新结果。
// 动态规划核心代码示例
boolean[] dp = new boolean[10000];
dp[0] = true;
for (int a : arr) {
for (int j = 0; j < 10000; j++) {
if (dp[j]) dp[j + a] = true;
}
}
1.2 区间DP:合并石子
题目描述:将N堆石子合并为一堆,求最小代价。
优化算法:GarsiaWachs算法(时间复杂度O(n logn))。
关键步骤:
- 寻找满足
stone[k-1] ≤ stone[k+1]
的最小k,合并stone[k]
和stone[k-1]
; - 递归处理合并后的序列。
二、搜索算法(DFS/BFS)深度解析
搜索算法是暴力枚举的优化,常用于路径问题和排列组合类题目。
2.1 DFS剪枝:日期统计问题
题目描述:从100个数字中找出合法日期序列的数量。
解题思路:
- DFS+剪枝:逐位匹配日期格式(如首位必须为2),剪枝无效路径;
- 合法性检查:通过月份和日期范围快速过滤非法结果。
// DFS剪枝核心代码片段
void dfs(int pos, int cnt, int date) {
if (cnt == 8) {
if (check(date)) ans++;
return;
}
// 剪枝条件:根据当前位置约束数字选择
if (条件匹配) dfs(pos+1, cnt+1, date*10+a[pos]);
dfs(pos+1, cnt, date); // 不选当前数字
}
2.2 BFS应用:岛屿数量问题
题目描述:计算矩阵中独立岛屿的数量。
实现方法:
- 遍历矩阵,对未访问的陆地启动BFS,标记所有连通区域;
- 使用队列存储待访问节点,方向数组控制移动。
三、贪心算法实战技巧
贪心算法通过局部最优解逼近全局最优,常见于区间调度问题。
3.1 区间不相交问题
题目描述:移除最小区间数使剩余区间互不重叠。
贪心策略:
- 按区间终点排序;
- 优先选择终点小的区间,为后续留出更大空间。
// 贪心排序与选择
Arrays.sort(intervals, (a, b) -> a[1] - b[1]);
int count = 1, end = intervals[0][1];
for (int[] interval : intervals) {
if (interval[0] >= end) {
count++;
end = interval[1];
}
}
四、数论与快速幂
数论题常涉及质数判断、模运算和快速幂。
4.1 快速幂算法
应用场景:计算大数幂取模(如a^b mod p
)。
迭代优化:将幂次分解为二进制,逐位计算。
long long qmi(long long a, int b, int p) {
long long res = 1;
while (b) {
if (b & 1) res = res * a % p;
a = a * a % p;
b >>= 1;
}
return res;
}
五、真题综合训练
5.1 冶炼金属(二分法)
题目描述:根据冶炼记录推导金属转换率的最小值和最大值。
解题思路:
- 对每个记录使用二分法,确定转换率的可行范围。
5.2 分糖果问题(模拟+循环)
题目描述:计算使所有孩子糖果数相同所需的补发次数。
实现要点:
- 模拟每轮分配过程,记录奇数次补发。
六、备考建议
- 掌握模板:熟记DP状态转移、BFS队列实现等核心代码;
- 真题训练:优先练习近3年真题,熟悉出题风格;
- 复杂度优化:学会剪枝、快速幂等优化技巧;
参考资料: