码迷,mamicode.com
首页 > 其他好文 > 详细

hdu 3709 Balanced Number(数位dp)

时间:2016-12-11 17:44:04      阅读:180      评论:0      收藏:0      [点我收藏+]

标签:++   ble   target   stream   区间   amp   get   i++   表示   

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3709

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

求力矩很显然可以想到dp[len][mid][cau],mid表示对称点,cau表示力矩大小。

然后很显然的记忆化索索

 

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
typedef long long ll;
ll x , y , dp[20][20][2000];
int dig[20];
ll dfs(int len , int mid , int cau , int flag) {
    if(!len)
        return cau == 0;
    if(cau < 0)
        return 0;
    if(!flag && dp[len][mid][cau] != -1)
        return dp[len][mid][cau];
    int t = flag ? dig[len] : 9;
    ll sum = 0;
    for(int i = 0 ; i <= t ; i++) {
        sum += dfs(len - 1 , mid , cau + i * (len - mid) , flag && i == t);
    }
    if(!flag)
        dp[len][mid][cau] = sum;
    return sum;
}
ll Gets(ll gg) {
    memset(dp , -1 , sizeof(dp));
    int len = 0;
    if(gg < 0)
        return 0;
    if(gg == 0)
        return 1;
    while(gg) {
        dig[++len] = gg % 10;
        gg /= 10;
    }
    ll ans = 0;
    for(int i = len ; i >= 1 ; i--) {
        ans += dfs(len , i , 0 , 1);
    }
    return ans - (len - 1);
}
int main() {
    int t;
    scanf("%d" , &t);
    while(t--) {
        scanf("%lld%lld" , &x , &y);
        printf("%lld\n" , Gets(y) - Gets(x - 1));
    }
    return 0;
}

hdu 3709 Balanced Number(数位dp)

标签:++   ble   target   stream   区间   amp   get   i++   表示   

原文地址:http://www.cnblogs.com/TnT2333333/p/6159810.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!