弱校联萌第三场 I 数位dp 好题,可以用来入门

来源:互联网 发布:做美工需要学什么 编辑:程序博客网 时间:2024/05/18 22:54

                                   点击打开题目链接 

题意就不说了,求 [l-r] momo数,

代码里有详解

#include <stdio.h>#include <algorithm>#include <string.h>#include <iostream>using namespace std;typedef long long LL;LL dp[20][10][3],f[20];int a[20];LL dfs(int p,int x,int lis,int flag){    ///p 表示长度 x 表示当前位 lis=0表示全相等,lis=1表示非递增lis=2表示非递减 ,flag标记是不是上界    if(p<=1)        return 1;    if(dp[p][x][lis]!=-1&&!flag)        return dp[p][x][lis];    int num;    LL ans=0;    num=flag?a[p-1]:9;///求下一位的上界是多少    for(int i=0; i<=num; i++)    {        int flag2=0;        if(i==num && flag)            flag2=1;        /// i表示下一位数字 x表示当前数字        if(i==x && lis==0 )            ans+=dfs(p-1,i,0,flag2);        if(i>=x && lis==1)            ans+=dfs(p-1,i,1,flag2);        if(i<=x && lis == 2)            ans+= dfs(p-1,i,2,flag2);    }    if(!flag)        dp[p][x][lis]=ans;    return ans;}LL solve(LL x){    LL ans=0;    int p=0;    while(x>0)    {        p++;        a[p]=x%10;        x=x/10;    }    for(int i=1; i<a[p]; i++)///只求长度为p的momo数个数,    {        ans+=dfs(p,i,1,0)+dfs(p,i,2,0)-dfs(p,i,0,0);    }    ans+=dfs(p,a[p],1,1)+dfs(p,a[p],2,1)-dfs(p,a[p],0,1);    return ans+f[p-1]; ///f[p-1] : 加上1 ~999...99 的momo数个数}int main(){    int t;    LL l,r;    LL x=0;    f[0]=0;    memset(dp,-1,sizeof(dp));    for(int i=1; i<19; i++)    {        x=x*10+9;        f[i]=solve(x);    }    cin>>t;    while(t--)    {        scanf("%lld%lld",&l,&r);        printf("%lld\n",solve(r)-solve(l-1));    }    return 0;}


0 0