【动态规划 C++动态规划】P10986 [蓝桥杯 2023 国 Python A] 2023|普及+

【动态规划 C++动态规划】P10986 [蓝桥杯 2023 国 Python A] 2023|普及+

本文涉及知识点

C++动态规划 数位dp

[蓝桥杯 2023 国 Python A] 2023

题目背景

建议使用 PyPy3 提交本题。

题目描述

给定 n , m n, m n,m,请求出所有 n n n 位十进制整数中有多少个数中恰好出现了 m m m 个 2023 2023 2023。

例如 00202312023 00202312023 00202312023 是一个 11 11 11 位的出现了 2 2 2 个 2023 2023 2023 的十进制整数。

由于结果可能很大,请输出答案对 998 , 244 , 353 998,244,353 998,244,353 取模的结果。

输入格式

输入一行包含两个整数 n , m n,m n,m,用一个空格分隔。

输出格式

输出一行包含一个整数表示答案。

样例 #1

样例输入 #1

5 1 

样例输出 #1

20 

提示

对于 40 % 40\% 40% 的评测用例, n ≤ 10 5 , m ≤ 10 n \le 10^5,m \le 10 n≤105,m≤10;

对于所有评测用例, 4 ≤ n ≤ 10 5 , 0 ≤ 4 m ≤ n 4 \le n \le 10^5,0 \le 4m \le n 4≤n≤105,0≤4m≤n。

P10986 # 数位dp
自定义状态:两部分合成int。第一部分:2023的数量i1,取值范围[0,m+1],超过m+1个,算m+1个。第二部分:i2,结尾是202,3;20,2,2;1;其它0。
202遇到3,i1++,i2=0。遇到0,i2=2,其它规则1。
20遇到2,i2++。其它规则1。
2遇到0,i2++。其它规则1。
规则1:遇到2,i2=1,否则i2=0。
时间复杂度: 每位的状态m,n位,字符集长度 ∑ \sum ∑是10。O(nm ∑ \sum ∑),超时。

组合数学 放球问题 容斥原理

f(x)记录至少x个2023的方案数。
x个2023,插入n-4x个数。 i f f iff iff n-4x个相同的球,放到x+1个不同的盒子。n-4x个数,可以从0到9任意选择。
本题答案: f(m)-f(m+1)+f(m+2) ⋯ \cdots ⋯f(n/4)

代码

核心代码

#include<iostream>#include<sstream>#include<vector>#include<map>#include<unordered_map>#include<set>#include<unordered_set>#include<string>#include<algorithm>#include<functional>#include<queue>#include<stack>#include<iomanip>#include<numeric>#include<math.h>#include<climits>#include<assert.h>#include<cstring>#include<bitset>usingnamespace std;template<classT=int> vector<T>Read(int n,constchar* pFormat ="%d"){ vector<T>ret(n);for(int i=0;i<n;i++){scanf(pFormat,&ret[i]);}return ret;}template<classT=int> vector<T>Read(constchar* pFormat ="%d"){int n;scanf("%d",&n); vector<T> ret; T d;while(n--){scanf(pFormat,&d); ret.emplace_back(d);}return ret;} string ReadChar(int n){ string str;char ch;while(n--){do{scanf("%c",&ch);}while(('\n'== ch)); str += ch;}return str;}template<classT1,classT2>voidReadTo(pair<T1, T2>& pr){ cin >> pr.first >> pr.second;}template<int MOD =1000000007>classC1097Int{public:C1097Int(longlong llData =0):m_iData(llData% MOD){} C1097Int operator+(const C1097Int& o)const{returnC1097Int(((longlong)m_iData + o.m_iData)% MOD);} C1097Int&operator+=(const C1097Int& o){ m_iData =((longlong)m_iData + o.m_iData)% MOD;return*this;} C1097Int&operator-=(const C1097Int& o){ m_iData =(m_iData + MOD - o.m_iData)% MOD;return*this;} C1097Int operator-(const C1097Int& o){returnC1097Int((m_iData + MOD - o.m_iData)% MOD);} C1097Int operator*(const C1097Int& o)const{return((longlong)m_iData * o.m_iData)% MOD;} C1097Int&operator*=(const C1097Int& o){ m_iData =((longlong)m_iData * o.m_iData)% MOD;return*this;} C1097Int operator/(const C1097Int& o)const{return*this* o.PowNegative1();} C1097Int&operator/=(const C1097Int& o){*this/= o.PowNegative1();return*this;}booloperator==(const C1097Int& o)const{return m_iData == o.m_iData;}booloperator<(const C1097Int& o)const{return m_iData < o.m_iData;} C1097Int pow(longlong n)const{ C1097Int iRet =1, iCur =*this;while(n){if(n &1){ iRet *= iCur;} iCur *= iCur; n >>=1;}return iRet;} C1097Int PowNegative1()const{returnpow(MOD -2);}intToInt()const{return(m_iData + MOD)% MOD;}private:int m_iData =0;;};template<classT>classCFactorial{public:CFactorial(int n):m_res(n +1){ m_res[0]=1;for(int i =1; i <= n; i++){ m_res[i]= m_res[i -1]* i;}} T Com(int iSel,int iCanSel)const{return m_res[iCanSel]/ m_res[iSel]/ m_res[iCanSel - iSel];} T Com(const vector<int>& cnt)const{ T biRet =1;int iCanSel = std::accumulate(cnt.begin(), cnt.end(),0);for(int j =0; j < cnt.size(); j++){ biRet *=Com(cnt[j], iCanSel); iCanSel -= cnt[j];}return biRet;} vector<T> m_res;};template<classT>classCBallBox{public:CBallBox(CFactorial<T>& fac,int cntBall,int cntBox):m_fac(fac),m_iN(cntBall),m_iM(cntBox){} T NotNotNot(){//球不同盒子不同不能为空returng(m_iM);} T NotIsNot(){//球不同盒子同不能为空returnNotNotNot()/ m_fac.m_res[m_iM];} T IsNotIs(){//球同盒子不同能为空return m_fac.Com(m_iM -1, m_iN + m_iM -1);} T IsNotNot(){//球同盒子不同不能为空if(m_iN < m_iM){return0;}return m_fac.Com(m_iM -1, m_iN -1);}constint m_iM, m_iN;//m_iN球,m_iM盒子protected: T g(int m)const{ T biRet;for(int i =0; i <= m; i++){auto cur = m_fac.Com(i, m)*Pow(T(m - i), m_iN);if(1& i){ biRet -= cur;}else{ biRet += cur;}}return biRet;} CFactorial<T>& m_fac;};classSolution{public:intAns(int n,int m){typedef C1097Int<998244353> BI; CFactorial<BI>fac(n); vector<BI> anss;auto Cnt =[&](int m){constint iBoxCnt = n -4* m; CBallBox<BI>cb(fac, iBoxCnt, m +1); BI c1 = cb.IsNotIs();auto ans = c1 *BI(10).pow(iBoxCnt); anss.emplace_back(ans);}; BI ans;for(int i =0;4*(i + m)<= n; i++){Cnt(m+i);constint sign =(i +1)%2*2-1; ans += anss.back()* sign*fac.Com(m,i+m);}return ans.ToInt();}};intmain(){#ifdef_DEBUGfreopen("a.in","r",stdin);#endif// DEBUGint n,m;scanf("%d%d",&n,&m);auto res =Solution().Ans(n,m);#ifdef_DEBUG /* Out(pa, "pa="); Out(vm, ",vm="); printf("n=%d", n);*/#endif cout << res << std::endl;return0;}

单元测试

TEST_METHOD(TestMethod11){auto res =Solution().Ans(5,1);AssertEx(20, res);}TEST_METHOD(TestMethod12){auto res =Solution().Ans(4,1);AssertEx(1, res);}TEST_METHOD(TestMethod13){auto res =Solution().Ans(9,2);AssertEx(30, res);}TEST_METHOD(TestMethod14){auto res =Solution().Ans(6,1);AssertEx(300, res);}TEST_METHOD(TestMethod15){auto res =Solution().Ans(14,3);AssertEx(1000, res);}TEST_METHOD(TestMethod16){auto res =Solution().Ans(20,3);AssertEx(525290362, res);}

扩展阅读

我想对大家说的话
工作中遇到的问题,可以按类别查阅鄙人的算法文章,请点击《算法与数据汇总》。
学习算法:按章节学习《喜缺全书算法册》,大量的题目和测试用例,打包下载。重视操作
有效学习:明确的目标 及时的反馈 拉伸区(难度合适) 专注
闻缺陷则喜(喜缺)是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛
失败+反思=成功 成功+反思=成功

视频课程

先学简单的课程,请移步ZEEKLOG学院,听白银讲师(也就是鄙人)的讲解。
https://edu.ZEEKLOG.net/course/detail/38771
如何你想快速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.ZEEKLOG.net/lecturer/6176

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 C++17
如无特殊说明,本算法用**C++**实现。

Read more

数据库SQL防火墙构建主动防御,让恶意SQL无处遁形

数据库SQL防火墙构建主动防御,让恶意SQL无处遁形

在数字化转型的浪潮中,数据已成为企业的核心资产。然而,SQL注入攻击如同潜伏在阴影中的“不速之客”,时刻威胁着数据库的安全。即使开发团队严守预编译、输入过滤等防线,遗留代码、第三方组件的漏洞或人为疏忽仍可能给攻击者可乘之机。难道只能被动挨打、疲于补漏吗? 金仓数据库(KingbaseES)V009R002C014版本内置的SQL防火墙,给出了一种更聪明的答案——从数据库内核层构建主动防御,让恶意SQL无处遁形,安全团队从此告别“亡羊补牢”,真正实现“规则先行”。 一、SQL注入:那个偷偷溜进房子的“不速之客” SQL注入的原理并不复杂,却极其致命:攻击者将恶意代码伪装成正常输入,欺骗数据库执行非预期操作。 举个简单的例子:一个登录表单中,用户在用户名栏输入 ' OR '1'='1,后台的查询语句可能就变成了: SELECT * FROM users WHERE OR '1'='

By Ne0inhk
Spring Boot + jQuery 前后端分离图书管理系统:从接口设计到问题排查

Spring Boot + jQuery 前后端分离图书管理系统:从接口设计到问题排查

图书管理系统 1.1 准备前端代码 在本地想要的可以去我的gitee中下载 library 的相关前端代码 1.2 约定前后端交互接口 需求分析 图书管理系统是⼀个相对较大一点的案例,咱们先实现其中的⼀部分功能. 用户登录 1. 登录接口 2. 图书列表展示 字段说明: 字段说明id图书 IDbookName图书名称author作者count数量price定价publish图书出版社status图书状态 1 - 可借阅 其他 - 不可借阅statusCN图书状态中文含义 3.4.3 服务器代码 创建图书类 BookInfo @Data public class BookInfo { //图书ID private Integer id; //书名 private String bookName; //作者 private String

By Ne0inhk

前端相关动画库(GSAP/Lottie/Swiper/AOS)

前端相关动画库对比与实战指南:GSAP / Lottie / Swiper / AOS 这四个库几乎覆盖了前端 90% 常见的动画与交互场景,下面从定位、使用场景、优缺点、学习曲线、2025–2026 年实际使用情况等维度进行详细对比,并附上核心代码示例。 1. 四个库快速对比表 库名主要用途核心优势主要劣势文件大小 (min+gzip)学习曲线2025–2026 流行度典型场景GSAP任意 DOM/SVG/Canvas 高性能动画功能最强大、时间线控制极强、生态完善需要学习 API,入门稍陡~35–45 KB★★★★☆★★★★★复杂交互、品牌站、H5 互动、滚动触发动画Lottie播放 After Effects 导出的 JSON 动画设计感强、动效一致性高、跨平台文件体积可能较大、性能不如 GSAP~60

By Ne0inhk

AI实体识别WebUI开发指南:自定义界面与功能扩展

AI实体识别WebUI开发指南:自定义界面与功能扩展 1. 背景与技术选型 在信息爆炸的时代,非结构化文本数据(如新闻、社交媒体内容、文档)占据了数据总量的80%以上。如何从中高效提取关键信息,成为自然语言处理(NLP)领域的核心挑战之一。命名实体识别(Named Entity Recognition, NER)作为信息抽取的基础任务,能够自动识别文本中的人名(PER)、地名(LOC)、机构名(ORG)等关键实体,广泛应用于知识图谱构建、智能客服、舆情分析等场景。 然而,传统NER系统多以命令行或API形式提供,对非技术用户不够友好。为此,构建一个可视化、可交互、易扩展的WebUI界面,成为提升用户体验和落地效率的关键。本文将围绕基于ModelScope RaNER模型的中文实体识别WebUI项目,深入讲解其架构设计、界面实现机制及功能扩展路径,帮助开发者快速搭建属于自己的AI语义分析工具。 本项目选择 RaNER(Robust Named Entity Recognition)

By Ne0inhk