题链:http://acm.hdu.edu.cn/showproblem.php?pid=4389
Here is a function f(x):
int f ( int x ) {
if ( x == 0 ) return 0;
return f ( x / 10 ) + x % 10;
}
2 1 10 11 20
Case 1: 10 Case 2: 3
数位dp学习链接:http://blog.csdn.net/cyendra/article/details/38087573
题意:相当于问区间内有多少数满足 X%(∑xi)==0。∑xi 是数字X的数位和。
做法:由于最多9位数,所以能够枚举∑xi,最大为81。 然后就是数位dp了。
sum是数位和,nwmod是取模结果,mod 是枚举的模
当数位和sum==mod并且,nwmod最后==0,成立计数。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <malloc.h>
#include <ctype.h>
#include <math.h>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
#include <stack>
#include <queue>
#include <vector>
#include <deque>
#include <set>
#include <map>
typedef long long LL;
const int maxn=81;
int dig[maxn];
int f[10][maxn][maxn][maxn];
//nwmod 数取模后 sum 数位和
LL dfs(int pos,int nwmod,int sum,int mod,int limit)
{
if (pos<0) return sum==mod&&nwmod==0;
if (!limit&&f[pos][nwmod][sum][mod]!=-1)
return f[pos][nwmod][sum][mod];
LL res=0;
int last=limit?dig[pos]:9;
for (int i=0;i<=last;i++)
{
res+=dfs(pos-1,(nwmod*10+i)%mod,sum+i,mod,limit&&(i==last));
}
if (!limit) f[pos][nwmod][sum][mod]=res;
return res;
}
LL solve(LL n){
int len=0;
while (n)
{
dig[len++]=n%10;
n/=10;
}
LL ans=0;
for(int i=1;i<=81;i++)//枚举最后的mod
{
ans+=dfs(len-1,0,0,i,1);
}
return ans;
}
int main()
{
int n;
int t;
int cas=1;
scanf("%d",&t);
int a,b;
memset(f,-1,sizeof f);
while(t--)
{
scanf("%d%d",&a,&b);
if(a>b)
swap(a,b);
printf("Case %d: %I64d\n",cas++,solve(b)-solve(a-1));
}
return 0;
}
/*
2
1 10
11 20
Sample Output
Case 1: 10
Case 2: 3
*/
原文:http://www.cnblogs.com/jzdwajue/p/7074579.html