标签:
http://acm.hdu.edu.cn/showproblem.php?pid=3709
2 0 9 7604 24324
10 897
/**
hdu 3709   数位dp(小思维)
解题思路:有一个很好的转化技巧,不然会超时。搜索的时候初始值定为f(x),然后最后和0比较。不要搜f(i) 和f(x)比较
*/
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <algorithm>
using namespace std;
typedef long long LL ;
LL dp[25][25][2000],l,r;
int bit[25];
LL dfs(int len,int pos,int sum,int flag)
{
    if(len<0)
    {
        //printf("%d %d>>>>\n",suml,sumr);
        return sum==0;
    }
    if(flag==0&&dp[len][pos][sum]!=-1)
        return dp[len][pos][sum];
    int end=flag?bit[len]:9;
    LL ans=0;
    for(int i=0;i<=end;i++)
    {
        //printf("len-1:%d\n",len-1);
        ans+=dfs(len-1,pos,(sum+(len-pos)*i),flag&&i==end);
    }
    if(flag==0)
    {
        dp[len][pos][sum]=ans;
    }
    return ans;
}
LL solve(LL n)
{
    if(n==-1)return 0;
    int len=0;
    while(n)
    {
        bit[len++]=n%10;
        n/=10;
    }
    LL ans=0;
    for(int i=0;i<len;i++)
    {
       // printf("len-1:%d\n",len-1);
        ans+=dfs(len-1,i,0,1);
    }
    return ans-len+1;
}
int main()
{
    int T;
    scanf("%d",&T);
    memset(dp,-1,sizeof(dp));
    while(T--)
    {
        scanf("%I64d%I64d",&l,&r);
        printf("%I64d\n",solve(r)-solve(l-1));
    }
    return 0;
}标签:
原文地址:http://blog.csdn.net/lvshubao1314/article/details/46355473