数位dp(一)——Loj #10166. 「一本通 5.3 练习 1」数字游戏

题目链接:https://loj.ac/problem/10166
题目大意
求区间[a,b]有多少数字满足数位加和%N等于0。
解题思路
看范围,很明显的数位dp。我们设定状态dp[pos][N][i]表示在%N的情况下,到第pos位,数位加和%N是i,会有多少数字满足数位加和%N等于0。
之后就是很easy的套模板环节。
AC代码

#include <iostream>
#include <stdio.h>
#include <cstring>
#include <algorithm>
using namespace std;
int dp[40][105][105];//dp[pos][N][i]表示在%N情况下到第pos位数位之和%N为i的满足条件有多少
int a[40];
int x,y,N,cnt;
void init(int n)
{
    cnt=0;
    while(n)
    {
        a[++cnt]=n%10;
        n/=10;
    }
}
int dfs(int pos,int limit,int mod)
{
    if(!pos)
    return mod==0;
    if(!limit&&dp[pos][N][mod]!=-1)
    return dp[pos][N][mod];
    int up=limit?a[pos]:9;
    int ans=0;
    for(int i=0;i<=up;++i)
    {
        ans+=dfs(pos-1,limit&&i==up,(mod+i)%N);
    }
    if(!limit)
    dp[pos][N][mod]=ans;
    return ans;
}
int main()
{
    memset(dp,-1,sizeof(dp));//别忘记初始化
    while(~scanf("%d%d%d",&x,&y,&N))
    {
        init(x-1);
        int l=dfs(cnt,1,0);
        init(y);
        int r=dfs(cnt,1,0);
        printf("%d\n",r-l);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_44491423/article/details/108147874