数位dp例题模板题(后续更新)

描述:数位dp的问题题型一般是给定一个闭区间[L,R],求这个区间中满足“某种条件”的数的个数的总数
对于这类问题,我们首先统计[L,R]范围的满足条件的数字转化成统计[1,N]内满足条件的数字的数量
那么 Ans[L,R]=Ans[1,R]-Ans[1,L-1];
这样接下来讨论问题我们只需要考虑上边界即可
现在考虑统计[1,12345]内“魔法数的数量”
首先我们将长度<=5的数字补全前导0到五位
1->00001 ,123->00123
这样的映射一定是一一对应的,假设数字x补全前导0后为x
那么一个数x<=12345等同于x字典序<=12345

dfs求解

我们把这两种限制条件合并到了考虑数位的维度
最直观的解决方法:从最高位到最低位枚举,我们用dfs来解决这个过程
对于这道题的DFS要记录的状态
1.现在枚举到了哪一位
2.前面的一位数字是多少
3.这一位可以填哪些数字
由此可见对于x有两种可能性
(1):如果x前面的某一位已经小于上限数字对应位子的数字,这一位可以填0-9
(2):如果x前面的每一位数字都等于上线数字对应的数字,这一位可填的数字范围为0-上限数字对应位置的数字

所以我们只需要维护前面每一位是否都和上上限数字一样,就可以得到这个位置可填范围

int DSF(int pos,int pre_num,bool flag){
   //pos代表当前位数,pre_num代表当前位数的上一位,flag代表上一位是否和上限数字是否相等
	if(pos<=0)return 1;//如果已经枚举每一位,直接返回
	if(flag)max_num=upper_bound[pos] else max_num=9;//得出这一位可以填的最大数字
	int ret=0;
	for(int i=0;i<=max_num;i++){
   
		if(abs(i-pre_num)>=m){
   
			ret+=DFS(pos-1,i,flag&&(i==upper_bound[pos]));
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值