HDU3709 Balanced Number —— 数位DP
题目链接: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
to calculate the number of balanced numbers in a given range [x, y].
0 9
7604 24324
897
题解:
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的更多相关文章
- hdu3709 Balanced Number (数位dp+bfs)
Balanced Number Problem Description A balanced number is a non-negative integer that can be balanced ...
- hdu3709 Balanced Number 数位DP
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3709 题目大意就是求给定区间内的平衡数的个数 要明白一点:对于一个给定的数,假设其位数为n,那么可以有 ...
- HDU3709:Balanced Number(数位DP+记忆化DFS)
Problem Description A balanced number is a non-negative integer that can be balanced if a pivot is p ...
- HDU 3709 Balanced Number (数位DP)
Balanced Number Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others) ...
- hdu3709 Balanced Number 树形dp
A balanced number is a non-negative integer that can be balanced if a pivot is placed at some digit. ...
- Balanced Number 数位dp
题意: 给出求ab之间有多少个平衡数 4139为平衡数 以3为轴 1*1+4*2==9*1 思路很好想但是一直wa : 注意要减去前导零的情况 0 00 000 0000 不能反复计 ...
- [HDU3709]Balanced Number
[HDU3709]Balanced Number 试题描述 A balanced number is a non-negative integer that can be balanced if a ...
- 多校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 用作标记,当现在枚举的数小 ...
- HDU3709 Balanced Number (数位dp)
Balanced Number Time Limit:3000MS Memory Limit:0KB 64bit IO Format:%lld & %llu Descript ...
随机推荐
- 【BZOJ3450】Easy(期望)
题意: 某一天WJMZBMR在打osu~~~但是他太弱逼了,有些地方完全靠运气:(我们来简化一下这个游戏的规则有n次点击要做,成功了就是o,失败了就是x,分数是按comb计算的,连续a个comb就有a ...
- DP的序--Codeforces956E. Wardrobe
$n \leq 10000$个盒子,有高度,高度总和$\leq 10000$,盒子有重要的和不重要的,问最多有多少重要盒子的底端在区间$[L,R]$. 这是个入门级的DP,但需要一点胆量MD这题能放D ...
- PatentTips - Optimizing Write Combining Performance
BACKGROUND OF THE INVENTION The use of a cache memory with a processor facilitates the reduction of ...
- perl学习之精髓中的精髓
1.是函数就有返回值: 比如:chomp函数,其可以除去换行符,但其也有返回值 chomp($xx) #这是去除xx的换行符 $yy=chomp($xx) #这是看这次除去了几个换行符,也就是函数运 ...
- Xen虚拟化
Xen虚拟化基础 Xen虚拟化类型 hypervisor Xen组件 Xen hypervisor Colletion CPU.Memory.Interrupter Domain0 ---> D ...
- Netty构建游戏服务器(一)--基本概念与原理
一,Netty是什么 1,Netty是由 JBOSS提供的一个 java开源框架. 2,Netty是JAR包,一般使用ALL-IN-ONE的JAR包就可以开发了. 3,Netty不需要运行在Tomca ...
- 【面试 JDK】【第一篇】Object类面试详解
1.Object类有哪些方法 1>clone()方法 保护方法,实现对象的浅复制,只有实现了Cloneable接口才可以调用该方法,否则抛出CloneNotSupportedException异 ...
- Android应用开发 WebView与服务器端的Js交互
最近公司再添加功能的时候,有一部分功能是用的html,在一个浏览器或webview中展示出html即可.当然在这里我们当然用webview控件喽 WebApp的好处: 在应用里嵌套web的好处有这么几 ...
- tcp三次握手和syn 洪水攻击
1. 连接后,所有的 ack 为1才有效(连接后,ack 也一般都是1) 2. 建立连接3次握手, 如何确认对方收到了你发的包, seq 是自己发出去的,自己知道seq的值.所以怎么确认对方收到了自己 ...
- Linux下Tomcat VM參数改动
不可行的方法 最初我直接改动catalina.sh, 将JAVA_OPTS变量加上了 -server -Xms1G -Xmx1G -XX:+UserG1GC 最初看起来没啥问题,可是当服务器运行几天后 ...