题目链接:
http://acm.hust.edu.cn/vjudge/problem/26785
题目大意:
能被K整数且各位数字之和也能被K整除的数
解题思路:
状态表示:dp[pos][mod][sum],表示pos位之前的mod值以及每一数位的和
很单纯的数位dp。
其余的数位dp套路细节,详见:(本题与下题链接类似)
http://blog.csdn.net/qq_28302731/article/details/52173767
代码如下:
#include <iostream>
#include <string.h>
#include <stdio.h>
using namespace std;
int dp[15][1001][100];
int a[15];
int k;
int dfs(int pos,int mod,int sum,int limit)
{
if(pos<1)
return mod==0&&(sum%k==0);
if(!limit&&dp[pos][mod][sum] != -1)
return dp[pos][mod][sum];
int next = limit? a[pos]:9;
int ans = 0;
for(int i=0;i<=next;i++)
{
int modx=(mod*10+i)%k;
int sumx = sum+i;
ans += dfs(pos-1,modx,sumx,limit&&(i==next));
}
if(!limit)
dp[pos][mod][sum] = ans;
return ans;
}
int solve(int n)
{
int len=0;
while(n!=0)
{
a[++len]=n%10;
n /= 10;
}
int ans=dfs(len,0,0,1);
return ans;
}
int main()
{
int l,r,x=1;
int t;
cin>>t;
while(t--)
{
cin>>l>>r>>k;
memset(a,0,sizeof(a));
memset(dp,-1,sizeof(dp));
cout<<"Case "<<x<<": ";
x++;
cout<<solve(r)-solve(l-1)<<endl;
}
return 0;
}