您的位置:首页 > 编程语言 > Go语言

HDU 4722 Good Numbers(位数DP)(2013 ACM/ICPC Asia Regional Online ―― Warmup2)

2013-09-11 22:17 363 查看
Description

If we sum up every digit of a number and the result can be exactly divided by 10, we say this number is a good number. You are required to count the number of good numbers in the range from A to B, inclusive.

Input

The first line has a number T (T <= 10000) , indicating the number of test cases. Each test case comes with a single line with two numbers A and B (0 <= A <= B <= 10 18).

Output

For test case X, output "Case #X: " first, then output the number of good numbers in a single line.

题目大意:求a~b中,位上所有数字加起来能整除10的数有多少个。

思路:位数DP。dp[i][j][k]表示第i位小于j,除以10余k的数的个数,j=10只是为了i+1的j=1准备的……第一次写这个写得有点挫啊……

PS:有数学方法但是我不会,我只知道接近于对于0~n接近于n/10……

代码(109MS):

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;

const int MAXN = 22;

LL dp[MAXN][MAXN][MAXN];
//i位,字头小于j,和为k的数一共有多少个
LL a, b;
int T;

void init() {
dp[0][10][0] = 1;
for(int i = 1; i <= 19; ++i) {
for(int k = 0; k <= 9; ++k) dp[i][1][k] = dp[i - 1][10][k];
for(int j = 2; j <= 10; ++j) {
for(int k = 0; k <= 9; ++k)
dp[i][j][k] = dp[i][1][(k + 10 - (j - 1)) % 10] + dp[i][j - 1][k];
}
}
}

int t[MAXN];

LL calculate(LL n) {
int cnt = 0;
while(n) t[++cnt] = n % 10, n /= 10;
int sum = 0;
LL ret = 0;
for(int i = cnt; i > 0; --i) {
ret += dp[i][t[i]][(10 - sum) % 10];
sum = (sum + t[i]) % 10;
}
return ret;
}

int main() {
ios::sync_with_stdio(false);
cin>>T;
init();
for(int t = 1; t <= T; ++t) {
cin>>a>>b;
cout<<"Case #"<<t<<": "<<calculate(b + 1) - calculate(a)<<endl;
}
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐