AcWing1084 数字游戏II(数位dp)

y总的数位dp板子有点东西的,没有用记忆化搜索这东西。这题还是套板子,因为是模数,所以我们还是考虑建立状态为f[][][],表示前i个,最高位填j,模为k的值

#include<iostream>
#include<vector>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=1e5+10;
int f[20][10][101];
int p,a,b;
int mod(int a){
    return (a%p+p)%p;
}
void init(){
    int i;
    memset(f,0,sizeof f);
    for(i=0;i<=9;i++){
        f[1][i][i%p]++;
    }
    int j,k,x;
    for(i=2;i<=15;i++){
        for(j=0;j<=9;j++){
            for(k=0;k<p;k++){
                for(x=0;x<=9;x++){
                    f[i][j][k]+=f[i-1][x][mod(k-j)];
                }
            }
        }
    }
}
int dp(int n){
    if(!n)
    return 1;
    vector<int> num;
    while(n){
        num.push_back(n%10);
        n/=10;
    }
    int res=0;
    int last=0;
    int i;
    for(i=num.size()-1;i>=0;i--){
        int x=num[i];
        int j;
        for(j=0;j<x;j++){
            res+=f[i+1][j][mod(-last)];
        }
        last+=x;
        if(!i&&last%p==0)
        res++;
    }
    return res;
}
int main(){
    while(cin>>a>>b>>p){
    init();
    cout<<dp(b)-dp(a-1)<<endl;
    }
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/ctyakwf/p/12660061.html
今日推荐