总结数位DP算法.docx

总结数位DP算法.docx

ID:62242491

大小:40.47 KB

页数:6页

时间:2021-04-22

总结数位DP算法.docx_第1页
总结数位DP算法.docx_第2页
总结数位DP算法.docx_第3页
总结数位DP算法.docx_第4页
总结数位DP算法.docx_第5页
资源描述:

《总结数位DP算法.docx》由会员上传分享,免费在线阅读,更多相关内容在应用文档-天天文库

1、数位dp是一种计数用的dp,一般就是要统计一个区间[le,ri]内满足一些条件数的个数。比如,[1,10000]中统计不含有4的数。所谓数位dp,字面意思就是在数位上进行dp咯。就是对数字每一位每一位递推此类题目最基本的暴力方法:1.for(inti=le;i<=ri;i++)2.if(Check(i))ans++;而数位DP就是从最低(高)位起,一位一位的放数字,然后记忆化一下,累加一下有两种方法,一是递推,二是记忆化搜索一,记忆化搜索:思路来自:数位dp总结之从入门到模板假设题目要求是不含有62的数状态定义:d[pos][pr

2、e]表示当前枚举到pos位置,且pos+1位的数字是时满足题意的数字的个数(也即是pre==6时,pos该位置不能放2)还要个数组a[i]保存第i位的数字,如213,a[0]=3,注意是从右往左数pre,此有个问题是枚举第pos位数时,此位置放数字的范围要判断一下,比如题目给出在[1,894]枚举的时候要判断是否在894以内比如,213,第一位放了2,那么第二位就只能放0~1,所以模板中用了个limit断pos前的几位数字是否与n一样,true的话只能枚举0~a[pos],false就是不然比题目要求的213大了判0~9,还有

3、个问题是前导0的问题,假如枚举5位数,你放的时候前2位都是00,那数字不变成3位了嘛,所以需要个lead保存前几位是否都是0,当然这是看题意的,有时候题目不要求,可以直接省去好了,看模板:1.typedeflonglongll;2.inta[20];3.lldp[20][state];//不同题目状态不同4.lldfs(intpos,/*state变量*/,boollead/*前导零*/,boollimit/*数位上界变量*/)//不是每个题都要判断前导零5.{6.//递归边界,既然是按位枚举,最低位是0,那么pos==-1说明这

4、个数我枚举完了7.if(pos==-1)return1;/*这里一般返回1,表示你枚举的这个数是合法的,那么这里就需要你在枚举时必须每一位都要满足题目条件,也就是说当前枚举到pos位,一定要保证前面已经枚举的数位是合法的。不过具体题目不同或者写法不同的话不一定要返回1*/8.//第二个就是记忆化(在此前可能不同题目还能有一些剪枝)9.if(!limit&&!lead&&dp[pos][state]!=-1)returndp[pos][state];10./*常规写法都是在没有限制的条件记忆化,这里与下面记录状态是对应,具体为什么是

5、有条件的记忆化后面会讲*/11.intup=limit?a[pos]:9;//根据limit判断枚举的上界up;这个的例子前面用213讲过了12.llans=0;13.//开始计数14.for(inti=0;i<=up;i++)//枚举,然后把不同情况的个数加到ans就可以了15.{16.if()...17.elseif()...18.ans+=dfs(pos-1,/*状态转移*/,lead&&i==0,limit&&i==a[pos])//最后两个变量传参都是这样写的19./*这里还算比较灵活,不过做几个题就觉得这里也是套路了2

6、0.大概就是说,我当前数位枚举的数是i,然后根据题目的约束条件分类讨论21.去计算不同情况下的个数,还有要根据state变量来保证i的合法性,比如题目22.要求数位上不能有62连续出现,那么就是state就是要保存前一位pre,然后分类,23.前一位如果是6那么这意味就不能是2,这里一定要保存枚举的这个数是合法*/24.}25.//计算完,记录状态26.if(!limit&&!lead)dp[pos][state]=ans;27./*这里对应上面的记忆化,在一定条件下时记录,保证一致性,当然如果约束条件不需要考虑lead,这里就是

7、lead就完全不用考虑了*/28.returnans;29.}30.llsolve(llx)31.{32.intpos=0;33.while(x)//把数位都分解出来34.{35.a[pos++]=x%10;//个人老是喜欢编号为[0,pos),看不惯的就按自己习惯来,反正注意数位边界就行36.x/=10;37.}38.returndfs(pos-1/*从最高位开始枚举*/,/*一系列状态*/,true,true);//刚开始最高位都是有限制并且有前导零的,显然比最高位还要高的一位视为0嘛39.}40.intmain()41.{4

8、2.llle,ri;43.while(~scanf("%lld%lld",&le,&ri))44.{45.//初始化dp数组为-1,这里还有更加优美的优化,后面讲46.printf("%lld",solve(ri)-solve(le-1));4

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。