HDU3709

题目链接[kuangbin带你飞]专题十五 数位DP F - Balanced Number

题意:

给定区间[a,b],求区间内平衡数的个数。所谓平衡数即有一位做平衡点,左右两边数字的力矩想等。

题解:

枚举平衡点, 然后dp, 注意0参与计算了cnt次, 所以要减去cnt-1.

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

const int key = 9 * 18 * 18;
ll dp[20][20][key*2+10];
int dight[20];

ll dfs(int pos, int mid, int det, bool limit)
{
    if(!pos) return det == key;
    if(!limit && ~dp[pos][mid][det]) return dp[pos][mid][det];
    int up = limit ? dight[pos] : 9;
    ll res = 0;
    for(int i = 0;i <= up;i ++) {
        res += dfs(pos-1, mid, det + (pos-mid) * i, limit && i == dight[pos]);
    }
    if(!limit) dp[pos][mid][det] = res;
    return res;
}

ll solve(ll n)
{
    if(n == -1) return 0;
    int cnt = 0;
    while(n) {
        dight[++cnt] = n % 10;
        n /= 10;
    }
    ll res = 0;
    for(int i = cnt;i >= 1;i --) {
        res += dfs(cnt, i, key, 1);
    }
    return res - cnt + 1; //0多加了cnt-1次
}
int main()
{
    memset(dp, -1, sizeof(dp));
    int T;
    scanf("%d", &T);
    while(T --) {
        ll L, R;
        scanf("%lld %lld", &L, &R);
        printf("%lld\n", solve(R) - solve(L-1) );
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_36876305/article/details/80472534
今日推荐