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

Balanced Number

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

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
 
Author
GAO, Yuan
 
Source

题解:

1.对于一个数,我们枚举每个位置作为平衡点,去判断是否存在一个位置使得这个数左右平衡。对于非0的数,如果它是平衡数,那么它的平衡点只有一个。(因为假设aaaa0bbb这个数的平衡点0,如果把平衡点往左移,那么左边变轻,右边变重,原本是平衡的,那改变之后就往右倾斜了。同理平衡点往右移。)所以是+1,正好一一对应。但是对于0,它的任意一个位置都可以作为平衡点,所以需要去重。

2. dp[pos][pivot][num]:处理到pos位置,以pivot为平衡点,且左力矩比右力矩大num的情况下,有多少种情况。

问:

1.为什么dp数组要有“pivot”这一维,直接:dp[pos][num]不行吗?

答:虽然有num记录了当前位的“左力矩 - 右力矩”的大小,但是如果两种情况的pivot不同,那么在pos后面的位置,他们的值的变化是不一样的,即这两种情况不是等价的。只有在相同的位置pos下,他们的平衡点pivot相同,且“左力矩 - 右力矩”的大小且相同,后面位置的数字变化才是等价的。

2.dp[pos][leftnum][rightnum] 这样记录不行吗?

答:其实这样跟dp[pos][num]的情况是一样的,都没有记录平衡点pivot的位置,导致后面位置的数值变化可能不等价。

代码如下:

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <sstream>
#include <algorithm>
using namespace std;
typedef long long LL;
const double eps = 1e-;
const int INF = 2e9;
const LL LNF = 9e18;
const int MOD = 1e9+;
const int MAXN = 1e6+; int digit[];
LL dp[][][]; LL dfs(int pos, int pivot, int num, bool lim)
{
if(!pos) return (num==);
//剪枝,因为先加左边的,后减左边的,最终结果需要为0,如果过程中都出现负数,那减下去更加负,所以不可能符合条件
if(num<) return ;
if(!lim && dp[pos][pivot][num]!=-) return dp[pos][pivot][num]; LL ret = ;
int maxx = lim?digit[pos]:;
for(int i = ; i<=maxx; i++) //num+(pos-pivot)*i: 高位的加, 低位的减。这条式子很漂亮,刚好能满足力矩的计算
ret += dfs(pos-, pivot, num+(pos-pivot)*i, lim&&(i==maxx)); if(!lim) dp[pos][pivot][num] = ret;
return ret;
} LL solve(LL n)
{
int len = ;
while(n)
{
digit[++len] = n%;
n /= ;
} LL ret = ;
for(int i = ; i<=len; i++)
ret += dfs(len, i, , true); /*
为什么要减去len-1呢?原因是“0”这种情况,0在这里的表示是:000……00(len个0)。对于一个数
我们枚举每个位置作为平衡点,去判断是否存在一个位置使得这个数左右平衡。对于非0的数,如果
它是平衡数,那么它的平衡点只有一个,所以是+1,正好一一对应. 但对于000……00来说,它的每个
位置都可以作为平衡点( 因为左右两边都等于0),所以是+len,但是000……00却只是一个数,所以
需要减去重复计算的部分,即len-1.
*/
return ret-(len-);
} int main()
{
LL T, n, m;
scanf("%lld", &T);
memset(dp,-,sizeof(dp));
while(T--)
{
scanf("%lld%lld",&m,&n);
LL ans = solve(n) - solve(m-);
printf("%lld\n", ans);
}
return ;
}

HDU3709 Balanced Number —— 数位DP的更多相关文章

  1. hdu3709 Balanced Number (数位dp+bfs)

    Balanced Number Problem Description A balanced number is a non-negative integer that can be balanced ...

  2. hdu3709 Balanced Number 数位DP

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3709 题目大意就是求给定区间内的平衡数的个数 要明白一点:对于一个给定的数,假设其位数为n,那么可以有 ...

  3. HDU3709:Balanced Number(数位DP+记忆化DFS)

    Problem Description A balanced number is a non-negative integer that can be balanced if a pivot is p ...

  4. HDU 3709 Balanced Number (数位DP)

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

  5. hdu3709 Balanced Number 树形dp

    A balanced number is a non-negative integer that can be balanced if a pivot is placed at some digit. ...

  6. Balanced Number 数位dp

    题意: 给出求ab之间有多少个平衡数   4139为平衡数   以3为轴   1*1+4*2==9*1 思路很好想但是一直wa  : 注意要减去前导零的情况 0 00 000 0000   不能反复计 ...

  7. [HDU3709]Balanced Number

    [HDU3709]Balanced Number 试题描述 A balanced number is a non-negative integer that can be balanced if a ...

  8. 多校5 HDU5787 K-wolf Number 数位DP

    // 多校5 HDU5787 K-wolf Number 数位DP // dp[pos][a][b][c][d][f] 当前在pos,前四个数分别是a b c d // f 用作标记,当现在枚举的数小 ...

  9. HDU3709 Balanced Number (数位dp)

     Balanced Number Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Descript ...

随机推荐

  1. cf701E Connecting Universities

    Treeland is a country in which there are n towns connected by n - 1 two-way road such that it's poss ...

  2. 关于parseDouble用法

    1.JAVA中的compareTo方法和strcmp完全类似,你可以使用 if(greeting.compareTo("help")==0).....或者用s.quals(t)来判 ...

  3. 改变input的value值,同时在HTML中将value进行改变

    在使用lodop进行打印的时候,需求中有这样一个功能:某个字段可以在页面的input框中进行修改. 但是在进行打印时调用的是静态的HTML代码,这就导致在页面的input框中改变字段之后,但是HTML ...

  4. HDU 4770 Lights Against Dudely 暴力枚举+dfs

    又一发吐血ac,,,再次明白了用函数(代码重用)和思路清晰的重要性. 11779687 2014-10-02 20:57:53 Accepted 4770 0MS 496K 2976 B G++ cz ...

  5. poj 3083 dfs,bfs

    传送门    Children of the Candy Corn Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I6 ...

  6. JavaScript 实现格式化字符串函数String.format (解决引号嵌套转义符问题)

    在js开发中,我们可能会遇到这样一个问题 当需要通过js动态插入html标签的时候 特别是当遇到大量的变量拼接.引号层层嵌套的情况,会出现转义字符问题,经常出错 我们来看个例子 <!DOCTYP ...

  7. [delphi]修改indy源码后重新编译

    http://blog.csdn.net/nerdy/article/details/8702568 虽然indy有一身的毛病,但是一般情况下使用起来还是多方便的. 今天在做一个使用到indy的程序的 ...

  8. golang几种post请求方式

    get请求 get请求可以直接http.Get方法,非常简单. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 func httpGet() {     resp, err := h ...

  9. memcached优化方法

    工作原理     基本概念:slab,page.chunk.     slab,是一个逻辑概念. 它是在启动memcached实例的时候预处理好的,每一个slab相应一个chunk size.也就是说 ...

  10. vmware下安装mac os虚拟机问题,最后还是最终攻克了被一个小失误给陷害了

    今天决定来体验一下苹果系统.虚拟机文件大概用了一天半时间才下载完毕,解压后是39G大小,赶紧安装VMWARE.然后载入虚拟机文件体验.開始当我苹果标志出来的时候,我以为成功了.但是那个小齿轮一直在转, ...