luogu P2602 [ZJOI2010]数字计数

在这里插入图片描述

analysis

好久没碰blog了
这是所谓数位DP
数位dp是一种计数用的dp,一般就是要统计一个区间[l,r]内满足一些条件数的个数,这个条件一般都与大小无关(这不废话?不然还能叫DP?
然后对于这道题,使用记忆化搜索可以解决问题(记忆化搜索其实也是DP),即从高位到低位在限制范围内枚举可能性,然后记忆化一下,最后得解
感觉还没有把这东西学透

code

#include<bits/stdc++.h>
using namespace std;
#define loop(i,start,end) for(register int i=start;i<=end;++i)
#define clean(arry,num) memset(arry,num,sizeof(arry))
#define max(a,b) ((a>b)?a:b)
#define min(a,b) ((a<b)?a:b)
#define ll long long
ll dp[19][19],num[19];
ll dfs(register int pos,register bool lim,register bool lead,register int sum,register int dig){
    register ll res=0;register int up=((lim)?num[pos]:9);
    if(lead&&!lim&&dp[pos][sum]!=-1)return dp[pos][sum];if(!pos)return sum;
    loop(i,0,up)res+=dfs(pos-1,lim&&(i==up),lead||i,sum+((i||lead)&&(i==dig)),dig);
    if(lead&&!lim)dp[pos][sum]=res;return res;
}
inline ll work(register ll a,register int b){
    clean(dp,-1);register int cnt=0;
    while(a)num[++cnt]=a%10,a/=10;
    return dfs(cnt,1,0,0,b);
}
int main(){
    register ll a,b;scanf("%lld%lld",&a,&b);
    loop(i,0,9)printf("%lld ",work(b,i)-work(a-1,i));
    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AndrewMe8211

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值