HDU 4722:Good Numbers(数位DP)

类型:数位DP

题意:定义一个Good Number 为 一个数所有位数相加的和%10==0.问[A,B]之间有多少Good Number.

方法:

正常“暴力”的定义状态:(i,d,相关量)

定义dp[i][d][mod] 为 d开头的i位数中,%10==mod的数的个数

dp[i][d][mod] = sum(dp[i-1][0~9][(mod-d+10)%10]

出口:dp[1][d][mod] = (d==mod);

代码:

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
using namespace std;

long long dp[20][10][10];
int num[30];

long long dfs(int i, int d, int mod, bool isQuery) {
    if (i == 1) return d==mod;
    if (!isQuery && ~dp[i][d][mod]) return dp[i][d][mod];
    long long ans = 0;
    int end = isQuery?num[i-1]:9;
    int nextMod = (mod-d+10)%10;
    for (int j = 0; j <= end; j++) {
        ans += dfs(i-1, j, nextMod, isQuery && j == end);
    }
    if (!isQuery) dp[i][d][mod] = ans;
    return ans;
}

long long cal(long long x) {
    if (x == 0) return 1;
    if (x == -1) return 0;
    int len = 0;
    while (x) {
        num[++len] = x%10;
        x/=10;
    }
    return dfs(len+1, 0, 0, true);
}

int main() {
    int t;
    cin>>t;
    int cas = 1;
    memset(dp, -1, sizeof(dp));
    while (t--) {
        long long a,b ;
        cin>>a>>b;
        cout<<"Case #"<<cas++<<": "<<cal(b)-cal(a-1)<<endl;
    }
    return 0;
}
原文地址:https://www.cnblogs.com/shinecheng/p/3599250.html