HDU - 3709 - Balanced Number(数位dp)

http://acm.hdu.edu.cn/showproblem.php?pid=3709

题目大意:

问一个数满足(4139 is a balanced number with pivot fixed at 3. The torqueses are 42 + 11 = 9 and 9*1 = 9, for left part and right part, respectively.)即为平衡数,问你在一个区间[l,r]有多少平衡数

思路:

明显的数位dp,暴力枚举数字的每一位作为中心,而左右两边相加必为0,所以可写

AC代码:

#include <iostream>
#include <string.h>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <stdio.h>
#include <deque>

using namespace std;

#define LL long long
#define ull unsigned long long
#define INF 0x3f3f3f3f
#define inf 1000000000000000000
#define maxn 1005
#define eps 0.00000001
#define PI acos(-1.0)
#define M 1000000007

int num[20];
LL dp[20][20][2005];

LL dfs(int pos, int x, int status, bool limit) {
    if(!pos) return status == 0;
    if(status < 0)  return 0;
    if(!limit && dp[pos][x][status] != -1)  return dp[pos][x][status];
    int endi = limit ? num[pos] : 9;
    LL ans = 0;
    for (int i = 0; i <= endi; i ++)
        ans += dfs(pos - 1, x, status + i * (pos - x), limit && (i == endi));
    return limit ? ans : dp[pos][x][status] = ans;
}

LL solve(LL n) {
    num[0] = 0;
    while(n) {
        num[++num[0]] = n % 10;
        n /= 10;
    }
    LL ans = 0;
    for (int i = 1; i <= num[0]; i++) ans += dfs(num[0], i, 0, 1);
    return ans - num[0] + 1;
}

int main(int argc, const char * argv[]) {
    int T;
    scanf("%d", &T);
    memset(dp, -1, sizeof(dp));
    while(T --) {
        LL l, r;
        scanf("%lld %lld", &l, &r);
        printf("%lld\n", solve(r) - solve(l - 1));
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/henu_jizhideqingwa/article/details/82857074