Balanced Number(数位dp,枚举平衡点)

题目链接
大意:平衡数有平衡点,使平衡点两边的权值(数值)×权重(到平衡点的距离)和相等

对于任意一个平衡数,它的平衡点唯一
枚举平衡点统计平衡数的个数

注意0的情况,0有一个平衡点,但是00有两个平衡点,000有三个平衡点

#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll dp[20][20][4000];
int len;
int dig[20];
ll dfs(int pos,int piv,int sum,bool limit){
    if(pos==0){
        if(sum==2000) return 1;
        else return 0;
    }
    if(!limit&&dp[pos][piv][sum]!=-1) return dp[pos][piv][sum];
    int i;
    int up = limit?dig[pos]:9;
    ll ans=0;
    for(i = 0;i <= up;i ++){
        ans += dfs(pos-1,piv,sum+i*(pos-piv),limit&&i==up);
    }
    if(!limit)dp[pos][piv][sum] = ans;
    return ans;
}
ll solve(ll n){
    if(n==-1) return 0;
    len = 0;
    while(n!=0){
        dig[++len] = n%10;
        n /= 10;
    }
    int i;
    ll ans=0;
    for(i = 1;i <= len;i ++) ans+=dfs(len,i,2000,1);
    return ans-len+1;
}
int main()
{
    freopen("a.txt","r",stdin);
    ios::sync_with_stdio(0);
    int T;
    cin>>T;
    memset(dp,-1,sizeof(dp));
    while(T--){
        ll l,r;
        cin>>l>>r;
        cout<<solve(r)-solve(l-1)<<endl;
    }
    return 0;
}


猜你喜欢

转载自blog.csdn.net/qq_30358129/article/details/80462713