Balanced Number

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)
Total Submission(s): 9036    Accepted Submission(s): 4294

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
分析:对于这道题,如果一个数中每个数位到支点的距离*这个数位的和为0,那么这个数为平衡数.这样我们定义状态就要考虑力矩和和支点.支点可以在dfs前枚举得到,力矩和可以在处理每个数位的时候得到.但是这个算法是有缺陷的,例如0000,000000也会被统计,我们只需要减去给定范围0全是0的数的个数即可.这里可以进行一个小小的优化,如果力矩和已经为负数,说明已经处理到了支点左边,接着处理下去绝对会小于0,那么回溯即可
 
#include<iostream>
#include<string.h>
#define ll long long
using namespace std;
ll shu[], dp[][][];//dp[i][j][k],i是长度,j是支点,k是力矩和,dp[i][j][k]是以j为支点的平衡数的数量
ll dfs(ll len, ll zhidian, ll sum, bool shangxian)
{
if (len == )
return sum == ? : ;
if (sum < )//因为力矩和是从支点右边开始算的(sum>0),如果左边的力矩都处理完之后sum<0,那一定不是平衡数
return ;
if (!shangxian&&dp[len][zhidian][sum]!=-)
return dp[len][zhidian][sum];
ll mx, cnt = ;
mx = (shangxian ? shu[len] : );
for (ll i = ; i <= mx; i++)//注意是<=
{
ll temp = sum;
temp = temp + (len - zhidian)*i;//len会不断的被return ,细细体会
cnt = cnt + dfs(len - , zhidian, temp, i == mx && shangxian);
}
if (!shangxian)
dp[len][zhidian][sum] = cnt;
return cnt;
} ll solve(ll n)
{
ll len = ;
while (n)
{
shu[++len] = n % ;
n = n / ;
}
ll ans = ;
for (ll i = ; i <= len; i++)//支点是从1开始,因为最高位的数一定不是平衡数
ans = ans + dfs(len, i, , true);
return ans - (len - );//如果0是支点,程序也会判断是平衡数,但是不符合题意
}
int main()
{
ll l, r, t;
scanf("%lld", &t);
memset(dp,-,sizeof(dp));//如果默认0会TLE
while (t--)
{
scanf("%lld%lld", &l, &r);
printf("%lld\n", solve(r) - solve(l - ));
}
return ;
}

参考自https://www.cnblogs.com/zbtrs/p/6106783.html

hdu 3709 Balanced Number(平衡数)--数位dp的更多相关文章

  1. HDU 3709 Balanced Number 求区间内的满足是否平衡的数量 (数位dp)

    平衡数的定义是指,以某位作为支点,此位的左面(数字 * 距离)之和 与右边相等,距离是指某位到支点的距离; 题意:求区间内满足平衡数的数量 : 分析:很好这又是常见的数位dp , 不过不同的是我们这次 ...

  2. HDU 3709 Balanced Number (数位DP)

    Balanced Number Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) ...

  3. hdu 3709 Balanced Number(数位dp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3709 题意:给定区间[a,b],求区间内平衡数的个数.所谓平衡数即有一位做平衡点,左右两边数字的力矩相 ...

  4. HDU 3709 Balanced Number(数位DP)题解

    思路: 之前想直接开左右两边的数结果爆内存... 枚举每次pivot的位置,然后数位DP,如果sum<0返回0,因为已经小于零说明已经到了pivot右边,继续dfs只会越来越小,且dp数组会炸 ...

  5. HDU 3709 Balanced Number (数位DP)

    题意: 找出区间内平衡数的个数,所谓的平衡数,就是以这个数字的某一位为支点,另外两边的数字大小乘以力矩之和相等,即为平衡数. 思路: 一开始以为需要枚举位数,枚举前缀和,枚举后缀和,一旦枚举起来就会M ...

  6. HDU - 3709 - Balanced Number(数位DP)

    链接: https://vjudge.net/problem/HDU-3709 题意: A balanced number is a non-negative integer that can be ...

  7. hdu3709 (平衡数) 数位DP

    Balanced Number Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) ...

  8. HDU 3709 Balanced Number

    发现只要Σa[i]*i%Σa[i]==0就可以. #include<iostream> #include<cstdio> #include<cstring> #in ...

  9. SPOJ BALNUM Balanced Numbers 平衡数(数位DP,状压)

    题意: 平衡树定义为“一个整数的某个数位若是奇数,则该奇数必定出现偶数次:偶数位则必须出现奇数次”,比如 222,数位为偶数2,共出现3次,是奇数次,所以合法.给一个区间[L,R],问有多少个平衡数? ...

随机推荐

  1. CentOS 最新版的下载地址 + 版本选择详解

    CentOS 最新版的下载地址 + 版本选择详解 发现越来越多的机关单位.事业单位开始使用 Linux 作为主要服务器,毕竟,Linux的稳定性和高效性是众所周知的,所以我也打算把自己这一块技术加强一 ...

  2. 注册一个GitHub用户的过程

    今天,我注册了一个GitHub用户.一开始,不知道GitHub是什么,还以为叫什么"getup",心里还想着什么网站名字这么奇怪,后来在舍友的帮助之下知道了原来是叫GitHub.下 ...

  3. mysql数据表简单拷贝及重命名

    CREATE TABLE to LIKE from;//拷贝结构 RENAME TABLE from TO to;//重命名

  4. Javascript几个时髦的hack技巧《Javascript Hacks for Hipsters》

    转自:http://berzniz.com/post/68001735765/javascript-hacks-for-hipsters Javascript Hacks for Hipsters J ...

  5. 使用Docker、CoreOS、Mesos部署可扩展的Web应用

    [编者的话]本文作者重点介绍了如何使用Docker.CoreOS.Mesos.Vulcand.对象存储来部署一个可扩展的Web应用,他首先介绍了为什么要选择这些工具以及与其它工具相比这些工具的优势.紧 ...

  6. ansible常用ad hoc操作

    ansible group001 -i hosts.ip -m shell -a -v

  7. .net List方法属性及作用

    List的方法和属性 方法或属性 作用 Capacity 用于获取或设置List可容纳元素的数量.当数量超过容量时,这个值会自动增长.您可以设置这个值以减少容量,也可以调用trin()方法来减少容量以 ...

  8. ASP.NET MVC 防止CSRF攻击

    简介 MVC中的Html.AntiForgeryToken()是用来防止跨站请求伪造(CSRF:Cross-site request forgery)攻击的一个措施,它跟XSS(XSS又叫CSS:Cr ...

  9. c# 线程的基本使用

    创建线程 线程的基本操作 线程和其它常见的类一样,有着很多属性和方法,参考下表: 创建线程的方法有很多种,这里我们先从thread开始创建线程 class Program { static void ...

  10. 水平居中和transform: translateY(-50%) 实现元素垂直居中效果

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...