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

P1832 A+B Problem(再升级)

记录110

#include<bits/stdc++.h> using namespace std; long long dp[1010];//注意longlong bool f(int x){//判断素数 if(x<2) return false; for(int i=2;i*i<=x;i++){ if(x%i==0) return false; } return true; } int main(){//完全背包 int n; cin>>n; dp[0]=1;//dp起点 for(int i=2;i<=n;i++){//遍历数字 if(f(i)){//判断素数i for(int j=i;j<=n;j++) dp[j]+=dp[j-i];//用素数i来组成数字j } } cout<<dp[n];//输出 return 0;//结束程序 }

题目传送门https://www.luogu.com.cn/problem/P1832


突破口

给定一个正整数 n,求将其分解成若干个素数之和的方案总数。


🔍 一、题目核心理解

🎯 问题描述

给定一个正整数n,求将 n 表示为若干个素数之和的方案总数

✅ 注意:

  • 顺序不同视为同一种方案(例如2+55+2算一种)
  • 允许重复使用同一个素数(如2+2+3是合法的)
  • 每个加数必须是素数

这实际上是一个“用素数作为物品,组成总和为 n 的方案数”的问题。


📌 样例解析

输入 #1:n = 7

合法分解(不考虑顺序):

  1. 7
  2. 2 + 5
  3. 2 + 2 + 3

共 3 种 → 输出3

输入 #2:n = 20→ 输出26(无需手动验证)


🧠 二、解题思路:完全背包计数模型

关键观察

  • 素数可以重复使用(如两个 2)
  • 方案不考虑顺序(即组合而非排列)
  • 这正是完全背包的“组合类计数”问题

💡 对比:

  • 如果考虑顺序(如2+55+2不同),则是“排列型”,需外层遍历容量
  • 本题要求无序组合→ 应外层遍历物品(素数),内层遍历容量

动态规划设计

  • dp[j]:表示组成数字 j 的方案总数
  • 初始化:dp[0] = 1(空和,1 种方案)
  • 对每个素数p(从小到大枚举):
    • j = p to n
      • dp[j] += dp[j - p]

✅ 这样能保证:每种组合只按素数递增顺序生成一次,避免重复计数


分析代码

#include<bits/stdc++.h> using namespace std; long long dp[1010]; // dp[j]:组成 j 的方案数,注意可能很大,用 long long
  • n ≤ 1000,但方案数可能指数级增长(如 n=1000 时方案数极大)
  • 所以用long long防止溢出(题目未说取模,需存大数)
bool f(int x){ // 判断 x 是否为素数 if(x < 2) return false; for(int i = 2; i * i <= x; i++){ if(x % i == 0) return false; } return true; }
  • 标准的素数判断函数
  • x < 2→ 非素数
  • 试除到√x即可
int main(){ int n; cin >> n; dp[0] = 1; // 基础情况:和为 0 有 1 种方案(什么都不选)
for(int i = 2; i <= n; i++){ // 枚举所有可能的“物品”:2 到 n if(f(i)){ // 如果 i 是素数 for(int j = i; j <= n; j++) dp[j] += dp[j - i]; // 完全背包:用素数 i 更新 dp[j] } }

🔄 核心逻辑说明:

  • 外层循环:遍历所有可能的素数i(从 2 到 n)
  • 内层循环j = i to n正序!
    • 正序是完全背包的标志(允许重复使用)
    • dp[j] += dp[j - i]:表示在已有方案基础上,加入一个i

✅ 为什么这样不会重复计数?

  • 因为我们按素数从小到大依次加入
  • 所有方案都以“非递减素数序列”形式生成
  • 例如:2+2+3会被生成,但3+2+2不会(因为 3 在 2 之后才被考虑)
cout << dp[n]; // 输出组成 n 的方案总数 return 0; }

⚠️ 关键细节说明

细节说明
dp[0] = 1组合计数问题的标准起点
素数判断范围只需判断2..n,因为大于 n 的素数不可能用于组成 n
内层正序完全背包特征,允许多次使用同一素数
外层素数顺序保证组合无序,避免2+55+2被重复计算
数据类型long long防止方案数溢出(n=1000 时方案数可达数百万甚至更多)

📊 补充:为什么这是“完全背包”?

背包类型物品使用次数内层循环方向
0-1 背包每件最多1次倒序
完全背包每件无限次正序

本题中,每个素数可用任意多次(如多个 2),所以是完全背包


总结:问题与解法对应

题目要求DP 设计
分解为素数之和物品 = 所有 ≤n 的素数
允许重复完全背包
不考虑顺序外层遍历素数(从小到大)
求方案总数dp[j] += dp[j - p],初始化dp[0]=1
http://www.jsqmd.com/news/700794/

相关文章:

  • 2026年全国最新粉末冶金齿轮定制与高精度零件推荐名单,供应完全指南——如何快速找到技术可靠的国产替代方案 - 精选优质企业推荐官
  • 歌词滚动姬:免费开源的专业LRC歌词制作工具完整指南
  • 2026年浙江宁波粉末冶金齿轮定制厂家深度横评:高精度零件快速交付完全指南 - 精选优质企业推荐官
  • Marketch深度解析:Sketch设计到前端代码的终极自动化转换引擎
  • AgentGym:构建标准化评估平台,量化AI智能体规划与执行能力
  • NumPy数组操作在机器学习中的高效应用
  • ncmdump:5分钟掌握网易云音乐加密文件转换的终极指南
  • 026年最新浙江粉末冶金厂家深度评测:如何找到靠谱的新能源汽车传动系统零件定制商 - 精选优质企业推荐官
  • 告别毕设焦虑!百考通AI助你高效搞定毕业论文
  • 量子混合语言模型架构与IBM量子处理器实践
  • 2026年宁波粉末冶金齿轮定制厂家深度横评:如何找到靠谱的高精度零件供应商 - 精选优质企业推荐官
  • 【紧急预警】VSCode 2026默认配置正悄悄吞噬你62%可用内存!3步强制启用ZRAM压缩引擎(附patch脚本)
  • Go语言怎么操作Word文档_Go语言Word文档生成教程【精通】
  • 磁盘管理笔记
  • VMware Workstation Pro 17.6.4 正式更新|个人免费 + 安全修复,附官网直链 + 网盘下载
  • 音频频谱可视化分析:5个关键场景中Spek如何提升你的音频工作流 [特殊字符]
  • 2026年宁波粉末冶金齿轮定制厂家深度横评:高精度传动零件 - 精选优质企业推荐官
  • VSCode日志分析进入智能时代(2026正式版首发解读):LLM辅助日志聚类+异常模式自学习实录
  • 数据正态化处理技术:原理、方法与应用场景
  • React 自定义 Hook 的命名规范与执行上下文详解
  • PGSQL Phriday #010:日志分析
  • MAA明日方舟助手:如何让游戏日常从“肝“到“甘“?
  • VSCode 2026合规检查功能全解析,深度适配IEC 62304:2015 Ed2.1与UL 4600安全生命周期要求
  • 2026年4月5家日语考级网课实测解析:日语考级网课、早道日语、沪江网校日语、线上日语网课、羊驼日语、考研日语选择指南 - 优质品牌商家
  • AlphaAvatar:基于强化学习的虚拟角色物理运动生成技术解析
  • ARM硬件断点与BREAKWRITE命令详解
  • VSCode AI插件配置失效?深度解析node版本冲突、代理证书绕过、WSL2路径映射三大隐性故障根因
  • 2026年宁波粉末冶金齿轮定制加工厂家深度横评与官方联系指南 - 精选优质企业推荐官
  • 【限时公开】微软内部未文档化的Dev Containers高级API:如何通过vscode.devcontainer.* API动态注入环境变量与生命周期钩子
  • 梯度在机器学习中的核心作用与优化实践