数位dp-R

来源:互联网 发布:exe软件看源码 编辑:程序博客网 时间:2024/06/06 17:48

给出a,b,求出[a,b]中各位数字之和能整除原数的数的个数。
Sample Input
10 19
Sample Output
3

思路:

因为给出的数据最大为18位,那么各位之和不会超过18*9=162,我们申请170的数组就行

申请一个dp[30][170][170][2]分别代表 位数,当前数的和,我们要取得模,是否有边界限制

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
long long a[30];
long long dp[30][170][170][2];
long long dfs(int pos,int sum,int flag,int mod,bool limit)
{
    if(pos==0)return sum==0&&flag==0;            //sum为0说明存在这个各位和,flag为0说明取模为0
    if(dp[pos][sum][flag][limit]!=-1)return dp[pos][sum][flag][limit];
    long long lll=0;
    int shang=limit?a[pos]:9;
    for(int i=0;i<=shang;i++)
    {
        if(sum-i<0)
            break;
        lll+=dfs(pos-1,sum-i,(flag*10+i)%mod,mod,limit&&i==a[pos]);
    }
    dp[pos][sum][flag][limit]=lll;
    return lll;
}
long long slove(long long x)
{
    int pos=0;
    while(x)
    {
        a[++pos]=x%10;
        x/=10;
    }
    long long ans=0;
    for(int i=1;i<=pos*9;i++)
    {
        memset(dp,-1,sizeof(dp));
        ans+=dfs(pos,i,0,i,1);
    }
    return ans;
}
int main()
{
    long long l,f;
    while(cin>>l>>f)
    {
        cout<<slove(f)-slove(l-1)<<endl;
    }
}

原创粉丝点击