uva 11361 - Investigating Div-Sum Property(数位dp)

题意:题目大意:给出a,b,k,问说在[a,b]这个区间有多少n,满足n整除k,以及n的各个为上的数字之和也整除k。

分析:dp[i][nmod][smod]长度为i,该数对k的余数,各位和对k的余数。

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <queue>
#include <stack>
#include <cstdio>
#include <vector>
#include <string>
#include <cctype>
#include <complex>
#include <cassert>
#include <utility>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
typedef pair<int,int> PII;
typedef long long ll;
#define lson l,m,rt<<1
#define pi acos(-1.0)
#define rson m+1,r,rt<<11
#define All 1,N,1
#define read freopen("in.txt", "r", stdin)
const ll  INFll = 0x3f3f3f3f3f3f3f3fLL;
const int INF= 0x7ffffff;
const int mod =  1000000007;
int a,b,k;
int dp[35][110][110],bit[35];
int dfs(int i,int nmod,int smod,int e){
    if(i==0)return (nmod==0)&&(smod==0);
    if(!e&&dp[i][nmod][smod]!=-1)return dp[i][nmod][smod];
    int l=e?bit[i]:9;
    int num=0;
    for(int v=0;v<=l;++v){
        int tnmod=(nmod*10+v)%k;
        int tsmod=(smod+v)%k;
        num+=dfs(i-1,tnmod,tsmod,e&&(v==l));
    }
    return e?num:dp[i][nmod][smod]=num;
}
int solve(int x){
    int len=0;
    memset(dp,-1,sizeof(dp));
    while(x){
        bit[++len]=x%10;
        x/=10;
    }
    return dfs(len,0,0,1);
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--){
     scanf("%d%d%d",&a,&b,&k);
        if(k>=100)
           printf("0\n");
        else{
            printf("%d\n",solve(b)-solve(a-1));
        }
    }
return 0;
}

 

posted on 2015-07-27 08:43  积跬步、至千里  阅读(190)  评论(0编辑  收藏  举报

导航