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

【蓝桥杯】包子凑数

包子凑数

题目描述

小明几乎每天早晨都会在一家包子铺吃早餐。他发现这家包子铺有 NN 种蒸笼,其中第 ii 种蒸笼恰好能放 AiAi​ 个包子。每种蒸笼都有非常多笼,可以认为是无限笼。

每当有顾客想买 XX 个包子,卖包子的大叔就会迅速选出若干笼包子来,使得这若干笼中恰好一共有 XX 个包子。比如一共有 3 种蒸笼,分别能放 3、4 和 5 个包子。当顾客想买 11 个包子时,大叔就会选 2 笼 3 个的再加 1 笼 5 个的(也可能选出 1 笼 3 个的再加 2 笼 4 个的)。

当然有时包子大叔无论如何也凑不出顾客想买的数量。比如一共有 3 种蒸笼,分别能放 4、5 和 6 个包子。而顾客想买 7 个包子时,大叔就凑不出来了。

小明想知道一共有多少种数目是包子大叔凑不出来的。

输入描述

第一行包含一个整数 NN (1≤N≤1001≤N≤100)。

以下 N 行每行包含一个整数 AiAi​ (1≤Ai≤1001≤Ai​≤100)。

输出描述

一个整数代表答案。如果凑不出的数目有无限多个,输出 INF。

输入输出样例

示例 1

输入

2
4
5

输出

6

样例说明

凑不出的数目包括:1, 2, 3, 6, 7, 11。

示例 2

输入

2
4
6

输出

INF

样例说明

所有奇数都凑不出来,所以有无限多个

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 256M

总通过次数: 8165  |  总提交次数: 9840  |  通过率: 83%

难度: 困难   标签: 2017, 裴蜀定理, 省赛, 动态规划

问题分析:包子凑数(裴蜀定理 + 动态规划)

核心算法思路
  1. ​裴蜀定理应用​​:

    • 若所有蒸笼容量 Ai​ 的最大公约数 g=1,则存在无限多个无法凑出的数(输出 INF
    • 若 g=1,则无法凑出的数是有限的(需动态规划统计)。
  2. ​动态规划(完全背包)​​:

    • ​状态定义​​:dp[j] = true 表示能凑出 j 个包子。
    • ​初始化​​:dp[0] = true(0 个包子不需要任何蒸笼)
    • ​状态转移​​:

      for (每种蒸笼容量 a[i]) for (j = a[i]; j <= MAX; j++) dp[j] = dp[j] || dp[j - a[i]];

    • ​统计结果​​:遍历 dp[1..MAX],计数 dp[j] = false 的数量
算法步骤
  1. ​计算最大公约数​​:

    • 初始化 g=A0​,遍历 g=gcd(g,Ai​)。
    • 若 g=1,输出 INF 并结束。
  2. ​动态规划求解​​:

    • 设背包容量 MAX = 10000(因 Ai​≤100,最大不可凑数 <1002)
    • 对每种蒸笼容量更新 dp 数组。
  3. ​统计无法凑出的数量​​:

    • 遍历 dp[1..MAX],统计 false 的个数。

C++ 代码实现

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;// 计算最大公约数
int gcd(int a, int b) {return b == 0 ? a : gcd(b, a % b);
}int main() {const int MAX = 10000;  // 背包最大容量int n;cin >> n;vector<int> a(n);vector<bool> dp(MAX + 1, false);  // dp数组初始化// 输入并计算最大公约数int g = 0;for (int i = 0; i < n; i++) {cin >> a[i];g = (i == 0) ? a[i] : gcd(g, a[i]);}// 检查最大公约数if (g != 1) {cout << "INF" << endl;return 0;}// 动态规划(完全背包)dp[0] = true;  // 初始化:0个包子可凑出for (int i = 0; i < n; i++) {for (int j = a[i]; j <= MAX; j++) {if (dp[j - a[i]]) dp[j] = true;  // 状态转移}}// 统计无法凑出的数量int count = 0;for (int i = 1; i <= MAX; i++) {if (!dp[i]) count++;}cout << count << endl;return 0;
}

代码解析

  1. ​最大公约数计算​​:

    • 使用递归实现辗转相除法,时间复杂度 O(log(min(Ai​)))
  2. ​动态规划核心​​:

    • ​空间优化​​:使用一维 dp 数组,避免二维空间开销
    • ​完全背包逻辑​​:每种蒸笼无限使用,内层循环正序更新(区别于01背包的逆序)
  3. ​边界与效率​​:

    • ​背包容量​​:MAX=10000 的设定基于裴蜀定理(Ai​≤100 时最大不可凑数 <1002)
    • ​时间复杂度​​:O(N×MAX),满足 N≤100、MAX=104,1秒内可完成

示例验证

  • ​输入 [4, 5]​:
    • g=gcd(4,5)=1,动态规划后统计得无法凑出 {1,2,3,6,7,11},输出 6
  • ​输入 [4, 6]​:
    • g=gcd(4,6)=2=1,直接输出 INF
http://www.xdnf.cn/news/10878.html

相关文章:

  • 用Python训练自动驾驶神经网络:从零开始驾驭未来之路
  • VR线上展厅特点分析与优势
  • 计算机组成原理知识点汇总(五)计算机运算方法
  • web攻防之SSTI 注入漏洞
  • 黑马Java面试笔记之 集合篇(算法复杂度+ArrayList+)
  • 【数据库】安全性
  • 【笔记】使用Media Creation Tool给新主机装win10魔改iso
  • 00 Deep learning 之回归、拟合、逻辑回归
  • SAP学习笔记 - 开发20 - 前端Fiori开发 Nest View(嵌套视图) ,Fragment(片段)
  • 深入解析 MultipartFile:Spring 框架下的高效文件处理方案
  • backend 服务尝试连接 qdrant 容器,但失败了,返回 502 Bad Gateway 问题排查
  • [Java恶补day14] 56. 合并区间
  • JAVA获取ES连接并查询所有数据
  • RTP over TCP 模式
  • 如何用 pnpm patch 给 element-plus 打补丁修复线上 bug(以 2.4.4 修复 PR#15197 为例)
  • 4-C#的不同窗口传值
  • 洛谷P12610 ——[CCC 2025 Junior] Donut Shop
  • 转战海外 Web3 远程工作指南
  • (10)Fiddler抓包-Fiddler如何设置捕获Firefox浏览器的Https会话
  • 双周报Vol.73:移除使用方法实现 trait 、新增了 “错误多态” 功能、.语法支持使用 _ 的匿名函数...
  • 16QAM在瑞利信道下的性能仿真:从理论到实践的完整解析(附完整代码)
  • 【HarmonyOS 5】鸿蒙Taro跨端框架
  • 【TMS570LC4357】之相关驱动开发学习记录1
  • 总结:线程安全问题的原因和解决方案
  • 初识vue3(vue简介,环境配置,setup语法糖)
  • LlamaIndex的IngestionPipeline添加本地存储(本地文档存储)
  • Unity 环境搭建
  • 【springcloud】快速搭建一套分布式服务springcloudalibaba(四)
  • Python中join()方法完全指南:参数要求与常见用法解析
  • 【深度学习新浪潮】以Dify为例的大模型平台的对比分析