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

巧用数论与动态规划破解包子凑数问题

本文针对“包子凑数”问题,深入解析如何通过最大公约数(GCD)判断无法组成的数目是否无限,并结合动态规划高效求解有限情况下的具体数目。通过清晰的算法思路、代码实现及示例详解,揭秘数论与动态规划在组合问题中的巧妙应用,帮助读者掌握核心解题技巧。文章还包含复杂度分析与关键注意事项,适合算法学习者和编程爱好者阅读。

题目描述

小明想知道包子铺用给定的蒸笼规格能凑出多少种无法组成的包子数目。若无法组成的数目无限,输出 INF

输入格式

  • 第一行为整数 N N N(蒸笼种数)
  • 接下来 N N N 行每行一个整数 A i A_i Ai(每种蒸笼的包子数)

输出格式

  • 无法凑出的数目个数,若无限则输出 INF

问题分析

关键条件

若所有 A i A_i Ai 的最大公约数(GCD)不为 1,则无法组成的数目无限。例如,当所有数均为偶数时,无法组成任何奇数。

动态规划思路

当 GCD 为 1 时,使用动态规划判断每个数是否能被组成:

  • 定义 dp[i] 表示能否凑出 i 个包子。
  • 状态转移:若存在某个 A j A_j Aj 使得 dp[i - A_j] 为真,则 dp[i] 为真。

解题步骤

  1. 计算 GCD:若 GCD ≠ 1,直接输出 INF
  2. 动态规划求解:遍历 1 到 100000,统计无法组成的数目。

代码实现

#include<iostream>
#include<algorithm>
using namespace std;int N;
int num[110];
bool dp[100010];  // dp[i]表示能否组成i个包子// 计算最大公约数
int gcd(int a, int b) {return b == 0 ? a : gcd(b, a % b);
}int main() {cin >> N;int g = 0;  // 初始GCD为0for (int i = 1; i <= N; ++i) {cin >> num[i];g = gcd(g, num[i]);  // 更新GCD}// 若所有数的GCD不为1,输出INFif (g != 1) {cout << "INF" << endl;return 0;}dp[0] = true;  // 0个包子可以凑出// 动态规划填充数组for (int i = 1; i <= 100000; ++i) {for (int j = 1; j <= N; ++j) {if (i >= num[j] && dp[i - num[j]]) {dp[i] = true;  // 标记当前数目可凑}}}// 统计无法凑出的数目int res = 0;for (int i = 1; i <= 100000; ++i) {if (!dp[i]) ++res;}cout << res << endl;return 0;
}

复杂度分析

  • 时间复杂度 O ( N × M ) O(N \times M) O(N×M),其中 M = 1 0 5 M=10^5 M=105 为遍历的最大数, N N N 为蒸笼种数。
  • 空间复杂度 O ( M ) O(M) O(M),存储动态规划状态。

示例解释

样例输入1

2  
4  
5

输出:6
解释:无法凑出的数为 1, 2, 3, 6, 7, 11。

样例输入2

2  
4  
6

输出:INF
解释:所有奇数无法凑出,数目无限。

总结

本题结合数论(GCD判断)与动态规划,需注意:

  1. 先通过 GCD 判断是否为无限情况。
  2. 动态规划时需覆盖足够大的范围以确保正确性。

http://www.mrgr.cn/news/97537.html

相关文章:

  • 计算机面试八股(自整)
  • 无人机装调与测试
  • vue3 脚手架初始化项目生成文件的介绍
  • 七种驱动器综合对比——《器件手册--驱动器》
  • 十四届蓝桥杯Java省赛 B组(持续更新..)
  • babel-runtime 如何缩小打包体积
  • docker的几种网络模式
  • Java反射实战-特殊嵌套格式JSON自定义解析装配
  • 初阶C++笔记第一篇:C++基础语法
  • I²S协议概述与信号线说明
  • 10-MySQL-性能优化思路
  • 网络相关题目
  • LeetCode 热题 100_完全平方数(84_279_中等_C++)(动态规划(完全背包))
  • DMA 概念与讲解
  • 深度学习驱动的车牌识别:技术演进与未来挑战
  • 【c++深入系列】:类和对象详解(下)
  • 【团体程序涉及天梯赛】L1~L2实战反思合集(C++)
  • CmLicense授权损耗规避措施
  • Mysql专题篇章
  • Vue3 路由权限管理:基于角色的路由生成与访问控制