HDU 3709 数位DP

统计l -r  里面有多少个平衡的数字

abca   假如以b为平衡点   a*1==c*1+a*2  成立的话就是   

#include <iostream>
#include<string.h>
#include<stdio.h>
using namespace std ;

#define ll long long

int dig[20];
ll dp[20][20][2010];  //dp[i][j][k]到第i位  平衡位子为j 前面的和为k

int deal(ll n)
{
    int cnt=0;
    while(n)
    {
        dig[cnt++]=n%10;
        n=n/10;
    }
    return cnt;
}               
ll dfs(int len,int c,int sum,int e)
{
    if(len<0) //为0的话就是1
        return sum==0;
    if(sum<0) //和为负的
        return 0;
    if(!e&&dp[len][c][sum]!=-1)
        return dp[len][c][sum];
    int u=e?dig[len]:9;
    ll ans=0;
    for(int i=0;i<=u;i++)
        ans=ans+dfs(len-1,c,sum+(len-c)*i,e&&(i==u));
    if(!e)
        dp[len][c][sum]=ans;
    return ans;
}    
ll calc(ll n) 
{
    int len=deal(n);  
    ll ans=0;
    for(int i=0;i<len;i++)
        ans+=dfs(len-1,i,0,1);
    return ans-len+1;
}   

int main()
{
    memset(dp,-1,sizeof(dp));
    int t;
    scanf("%d",&t);
    while(t--)
    {
        ll a,b;   
        scanf("%lld%lld",&a,&b);
        printf("%lld\n",calc(b)-calc(a-1));
    }
    return 0;
}
View Code

 

    

 

posted on 2017-05-15 21:48  HelloWorld!--By-MJY  阅读(130)  评论(0编辑  收藏  举报

导航