zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    AcWing 852. spfa判断负环 边权可能为负数。
    面试题 02.01. 移除重复节点
    1114. 按序打印
    剑指 Offer 38. 字符串的排列
    557. 反转字符串中的单词 III
    645. 错误的集合
    面试题 05.03. 翻转数位
    1356. 根据数字二进制下 1 的数目排序
    748. 最短完整词
    剑指 Offer 32
  • 原文地址:https://www.cnblogs.com/shinecheng/p/3599250.html
Copyright © 2011-2022 走看看