hdu3709 数位dp(自身平衡的数字)

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

Problem Description

A balanced number is a non-negative integer that can be balanced if a pivot is placed at some digit. More specifically, imagine each digit as a box with weight indicated by the digit. When a pivot is placed at some digit of the number, the distance from a digit
to the pivot is the offset between it and the pivot. Then the torques of left part and right part can be calculated. It is balanced if they are the same. A balanced number must be balanced with the pivot at some of its digits. For example, 4139 is a balanced
number with pivot fixed at 3. The torqueses are 4*2 + 1*1 = 9 and 9*1 = 9, for left part and right part, respectively. It‘s your job

to calculate the number of balanced numbers in a given range [x, y].

Input

The input contains multiple test cases. The first line is the total number of cases T (0 < T ≤ 30). For each case, there are two integers separated by a space in a line, x and y. (0 ≤ x ≤ y ≤ 1018).

Output

For each case, print the number of balanced numbers in the range [x, y] in a line.

Sample Input

2
0 9
7604 24324

Sample Output

10
897
/**
hdu 3709   数位dp(自身平衡的数字)
题目大意:求给定区间内满足自身平衡的数的个数,所谓平衡,
          比如:4139 is a balanced number with pivot fixed at 3. The torqueses are 4*2 + 1*1 = 9 and 9*1 = 9, for left part and right part, respectively.
解题思路:枚举支点。dp[i][j][k] i表示处理到的数位,j是支点,k是力矩和。但是要要把全是0的数排除
*/
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
using namespace std;
typedef long long LL;

LL dp[20][20][2000];
int bit[25];

LL dfs(int pos,int level,int presum,int flag)
{
    if(pos==-1)return presum==0;
    if(presum<0)return 0;
    if(!flag&&dp[pos][level][presum]!=-1)
        return dp[pos][level][presum];
    int end=flag?bit[pos]:9;
    LL ans=0;
    for(int i=0; i<=end; i++)
    {
        ans+=dfs(pos-1,level,presum+(pos-level)*i,flag&&(i==end));
    }
    if(!flag)dp[pos][level][presum]=ans;
    return ans;
}

LL solve(LL n)
{
    int len=0;
    while(n)
    {
        bit[len++]=n%10;
        n/=10;
    }
    LL ans=0;
    for(int i=0; i<len; i++)
    {
        ans+=dfs(len-1,i,0,1);
    }
    return ans-(len-1);///去掉全部为0的情况
}
int main()
{
    int T;
    LL l,r;
    memset(dp,-1,sizeof(dp));
    scanf("%d",&T);
    while(T--)
    {
        scanf("%I64d%I64d",&l,&r);
        printf("%I64d\n",solve(r)-solve(l-1));
    }
    return 0;
}
时间: 2024-08-24 22:14:34

hdu3709 数位dp(自身平衡的数字)的相关文章

hdu3709 数位dp+bfs

Balanced Number Problem Description A balanced number is a non-negative integer that can be balanced if a pivot is placed at some digit. More specifically, imagine each digit as a box with weight indicated by the digit. When a pivot is placed at some

(数位DP)51NOD 1042 数字0-9的数量

给出一段区间a-b,统计这个区间内0-9出现的次数. 比如 10-19,1出现11次(10,11,12,13,14,15,16,17,18,19,其中11包括2个1),其余数字各出现1次. 输入 两个数a,b(1 <= a <= b <= 10^18) 输出 输出共10行,分别是0-9出现的次数 输入样例 10 19 输出样例 1 11 1 1 1 1 1 1 1 1 解:被这道题卡了好久...最后自己找了个数模拟了一边流程.举个例子简单说说:对于数5314,我们可以将它拆分为[5310

[数位dp] kuangbinoj 1012 bin巨的数

题意: 作为ACM史上年度重量级人物,bin巨目前已经掌握了史上最NB的数,群巨快来仰慕!!我们定义这样一个数,它里面的每一个数字都是成双成对出现 的,but,如果这个数里面存在0那么这也是NB的数,比如11,122122,12035,当然,需要剔除那些首位是0的数.我们的目标就是计算一个区 间内bin巨有多少NB数! 思路: 简单的数位dp,需要考虑每个数字出现的次数(0,1),是否有前导0,是否出现了0. 这里需要注意的就是0不是一个bin巨数. #include"cstdlib"

SHUOJ 1771 - 奇偶和(数位DP)

http://202.121.199.212/JudgeOnline/problem.php?id=1771 夏季赛H题 Description Input 第一行含有一个正整数 T,表示有 T 组测试数据. 每组数据只有一行,包含三个整数 L_i,R_i,m. 约定     T≤200:     0≤L≤R≤10^18:     |m|≤100. Output 对于每组测试用例,输出: 第一行:Case #: (# 要替换成对应的数字). 输出两个整数,用一个空格分割.分别为在 [L_i,R_

hdu3709(求区间内平衡数的个数)数位dp

题意:题中平衡数的定义: 以一个位置作为平衡轴,然后左右其他数字本身大小作为重量,到平衡轴的距离作为全职,实现左右平衡(即杠杆原理平衡).然后为区间[x,y]内平衡数的个数. (0 ≤ x ≤ y ≤ 1018) 解法:数位dp.如果一个数的平衡数,那么它的平衡轴位置是确定的.原来一直尝试数位dp在dfs时候列举平衡轴的位置,后来才意识到可以提前枚举平衡轴位置,然后再dfs,这样比较好写.dp[mid][pre][wei];表示对称轴是mid,计算第pre个位置以后需要力矩大小wei的数的个数.

51Nod 1009 数字1的个数 | 数位DP

题意: 小于等于n的所有数中1的出现次数 分析: 数位DP 预处理dp[i][j]存 从1~以j开头的i位数中有几个1,那么转移方程为: if(j == 1) dp[i][j] = dp[i-1][9]*2+pow(10,i-1);else dp[i][j] = dp[i-1][9]+dp[i][j-1]; 然后注意下对于每个询问统计的时候如果当前位为1需要额外加上他后面所有位数的个数,就是n%pow(10,i-1); 这样总复杂度log(n)*10 #include <bits/stdc++.

BZOJ_1833_[ZJOI2010]_数字计数_(数位dp)

描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1833 统计\(a~b\)中数字\(0,1,2,...,9\)分别出现了多少次. 分析 数位dp真是细节又多又容易出错,我都懒得看题解,所以也就懒得写题解了... 注意细节吧还是... 1 #include <bits/stdc++.h> 2 using namespace std; 3 4 typedef long long ll; 5 ll a,b; 6 ll A[10],B[10],n

数位DP入门:bzoj1833: [ZJOI2010]count 数字计数

膜拜了一下蔡大神....然后突然想起来一些东西然后就填了一个半年多前的坑= = 人生第一道自己写的数位DP...好吧以前是看题解然后也不知道为什么就过了的>_< 数位DP介绍: http://wenku.baidu.com/link?url=9OS5Ybpw5wx00ahrH8ED2oyIlR1uWwrxT8N4pEg27GgBt2T2hLe4sd_h1rmpY7P0HmeHIEDw9h6_K98dPhhjoMhD2TpKcS8w1X8cC_dkPp_ 接下来是题目地址: http://www

数位dp(求1-n中数字1出现的个数)

题意:求1-n的n个数字中1出现的个数. 解法:数位dp,dp[pre][now][equa] 记录着第pre位为now,equa表示前边是否有降数字(即后边可不可以随意取,true为没降,true为已降):常规的记忆化搜索 代码: /****************************************************** * author:xiefubao *******************************************************/ #p