[hdu 3709]数位dp

感觉数位dp的套路基本掌握了,一些细节的处理要注意。比如这次输入输出都要用long long的问题,因为这个wa了好几次。还有全是0算重的情况,0特判一下就可以了。

#include<bits/stdc++.h>
using namespace std;

long long dp[20][20][2000];
int b[20];

long long dfs(int pos,int preok,int z,int l)
{
    if (pos==-1) return l==0;
    if (l<0) return 0;
    if (preok && dp[pos][z][l]!=-1) return dp[pos][z][l];
    int up=preok?9:b[pos];
    long long ans=0;
    for (int i=0;i<=up;i++)
    {
        if (i<b[pos]||preok) ans+=dfs(pos-1,1,z,l+(pos-z)*i);
        else ans+=dfs(pos-1,0,z,l+(pos-z)*i);
    }
    if (preok) dp[pos][z][l]=ans;
    return ans;
}


long long solve(long long n)
{
    int cnt=0;
    if (n<0) return 0;
    do {
        b[cnt++]=n%10;
        n/=10;
    }while (n);
    long long ans=0;
    for (int i=cnt-1;i>=0;i--) ans+=dfs(cnt-1,0,i,0);
    return ans-cnt+1;
}

int main()
{
    memset(dp,-1,sizeof(dp));
    int t;
    scanf("%d",&t);
    while (t--)
    {
        long long l,r;
        scanf("%I64d%I64d",&l,&r);
        printf("%I64d\n",solve(r)-solve(l-1));
    }
    return 0;
}

 

posted @ 2017-07-19 17:48  ACMsong  阅读(120)  评论(0编辑  收藏  举报