Balanced Number HDU - 3709

题目大意:若一个数以某个位置为支点,支点左右的加权和相同,这样的数被称为平衡数,求区间内平衡数的个数

思路:枚举支点位置,针对每个支点进行数位DP,但是0比较特殊,假设该数的长度为len,枚举len次支点位置,0会被重复计算len次,但我们只需要统计一次。

#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<stdlib.h>
#include<iostream>
using namespace std;
#define LL long long
#define INF 999999999

LL dp[20][20][5000];
int bit[20];

LL DFS(int pos,int k,int sum,int limit,int num)
{
    if(pos < 0)
    {
        if(sum == 0)
            return 1;
        return 0;
    }
    if(!limit && dp[pos][k][sum]!=-1)
        return dp[pos][k][sum];
    LL ans = 0;
    int len = limit?bit[pos]:9;
    for(int i=0;i<=len;i++)
    {
        int temp = sum + (pos-k)*i;
        ans += DFS(pos-1,k,temp,limit&&i==len,num*10+i);
    }
    if(!limit)
        dp[pos][k][sum] = ans;
    return ans;
}

LL Solve(LL n)
{
    int pos = 0;
    LL ans = 0;
    while(n)
    {
        bit[pos++] = n%10;
        n/=10;
    }
    for(int k=0;k<pos;k++)
    {
        ans += DFS(pos-1,k,0,1,0);
    }
    return ans-pos+1;
}

int main()
{
    int T;
    LL n,m;
    scanf("%d",&T);
    memset(dp,-1,sizeof(dp));
    while(T--)
    {
        scanf("%I64d%I64d",&n,&m);
        LL ans = Solve(m) - Solve(n-1);
        printf("%I64d\n",ans);
    }
    return 0;
}
View Code

 

posted @ 2019-04-27 19:36  声声醉如兰  阅读(180)  评论(0编辑  收藏  举报