HDU - 3709 Balanced Number 数位dp

题目链接:https://vjudge.net/problem/HDU-3709

题意:有多少平衡数,例如:4139 is a balanced number with pivot fixed at 3. The torqueses are 4*2 + 1*1 = 9 and 9*1 = 9,

题解:所以每个数的平衡位置只能有一个

dp[ i ][ j ][ k ][ z ] 表示 平衡位置是 i ,后面还剩 j 个位置,前面已经计算得到pre + 4000,z表示是否有前导0

注意一点就是,如果计算到平衡位置,前面都是0的话,那么平衡位置就不能为0,这就是前导0的左右

最后加上0这个数,因为0没有被计算到

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
ll dp[20][20][8000][2];
int w[66], len;
ll dfs(int pos, int limit, int pre, int ph, int lead) {
    if(pos < 0) {
        return pre == 4000;
    }
    if(!limit && dp[ph][pos][pre][lead] != -1) return dp[ph][pos][pre][lead];
    int p = limit ? w[pos] : 9;
    ll res = 0;
    for(int i = 0; i <= p; i++) {
        if(pos == ph) {
            if(lead && i == 0) continue;
            res += dfs(pos - 1, limit && i == p, pre, ph, 1);    
        } else {
            res += dfs(pos - 1, limit && i == p, pre + (pos - ph) * i, ph, lead && i == 0);
        }
    }
    if(!limit) dp[ph][pos][pre][lead] = res;
    return res;
}
ll solve(ll x) {
    if(x == -1) return 0;
    int len = 0;
    while(x) {
        w[len++] = x % 10;
        x /= 10;
    }
    ll res = 0;
    for(int i = 0; i <= len - 1; i ++)
        res += dfs(len - 1, 1, 4000, i, 1);
    return res + 1;
}
int main() {
    ll l, r;
    memset(dp, -1, sizeof(dp));
    int T;
    scanf("%d", &T);
    while(T--) {
        scanf("%lld %lld", &l, &r);
        printf("%lld\n", solve(r) - solve(l - 1));
    }
    return 0;
} 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值