HDU3709 Balanced Number 题解 数位DP
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3709
题目大意:
求区间 \([x, y]\) 范围内“平衡数”的数量。
所谓平衡数是指:以某一位为支点,它左边的所有位的数乘以它到支点的距离之和等于它右边的所有位的数乘以它到支点的距离之和。
比如, \(4139\) 是平衡数,因为以 \(3\) 为支点,
- 左边的每一位数与距离的乘积和为 \(4 \times 2 + 1 \times 1 = 9\);
- 右边的每一位数与距离的乘积和为 \(9 \times 1 = 9\)
所以左右两边的数与距离的乘积和是相等的,所以 \(4139\) 是一个平衡数。
问题分析:
对于这道题,我们需要先枚举支点在哪一位,
然后,在确定支点所在的位的基础上,进行 数位DP 。
我们设状态 \(f[cid][pos][delta]\) 表示:
- 枚举的支点在第 \(cid\) 位,
- 当前所处的数位为 \(pos\),
- \(delta\) 为从最高位到第 \(pos + 1\) 位的每一位上的数字 \(num_i\) 与其与 \(col\) 位的距离的乘积和 \(\sum num_i \times (i-col)\)
然后我们开函数 dfs(int cid, int pos, int delta, bool limit)
,其中:
cid
、pos
、delta
的含义同上;limit
表示当前是否处于限制状态。
只要 pos<0
时 delta==0
则找到一种情况。
注意:因为枚举每一位 col
时,数字 \(0\) 的情况都会计算上去,所以需要在枚举每一位是都减去 \(0\) 的情况,最后再加上 \(0\) 的情况。
实现代码如下:
#include <bits/stdc++.h>
using namespace std;
long long f[20][20][1800], a[20];
void init() {
memset(f, -1, sizeof(f));
}
long long dfs(int cid, int pos, int delta, bool limit) {
if (pos < 0) return !delta;
if (!limit && f[cid][pos][delta] != -1) return f[cid][pos][delta];
int up = limit ? a[pos] : 9;
long long tmp = 0;
for (int i = 0; i <= up; i ++) {
int d = delta + (pos-cid)*i;
if (d < 0) continue;
tmp += dfs(cid, pos-1, d, limit && i==up);
}
if (!limit) f[cid][pos][delta] = tmp;
return tmp;
}
long long get_num(long long x) {
if (x < 0) return 0;
int pos = 0;
long long res = 0;
while (x) {
a[pos++] = x % 10;
x /= 10;
}
for (int cid = 0; cid < pos; cid ++) {
res += dfs(cid, pos-1, 0, true);
res -= 1; // 减去0的情况
}
return res + 1; // 加上0的情况
}
int T;
long long x, y;
int main() {
init();
scanf("%d", &T);
while (T --) {
scanf("%lld%lld", &x, &y);
printf("%lld\n", get_num(y) - get_num(x-1));
}
return 0;
}
HDU3709 Balanced Number 题解 数位DP的更多相关文章
- HDU3709 Balanced Number (数位dp)
Balanced Number Time Limit:3000MS Memory Limit:0KB 64bit IO Format:%lld & %llu Descript ...
- HDU 3709 Balanced Number(数位DP)题解
思路: 之前想直接开左右两边的数结果爆内存... 枚举每次pivot的位置,然后数位DP,如果sum<0返回0,因为已经小于零说明已经到了pivot右边,继续dfs只会越来越小,且dp数组会炸 ...
- 【HDU 3709】 Balanced Number (数位DP)
Balanced Number Problem Description A balanced number is a non-negative integer that can be balanced ...
- HDU - 3709 - Balanced Number(数位DP)
链接: https://vjudge.net/problem/HDU-3709 题意: A balanced number is a non-negative integer that can be ...
- [HDOJ3709]Balanced Number(数位dp)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3709 题意:求区间[L,R]内每一个数中是否存在一位,使得左边的各位数*距离=右边的各位数*距离(自己 ...
- HDU5179 beautiful number 题解 数位DP
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5179 题目大意: 给你一个数 \(A = a_1a_2 \cdots a_n\) ,我们称 \(A\) ...
- hdu 3709 Balanced Number(数位dp)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3709 题意:给定区间[a,b],求区间内平衡数的个数.所谓平衡数即有一位做平衡点,左右两边数字的力矩相 ...
- HDU 3709 Balanced Number (数位DP)
题意: 找出区间内平衡数的个数,所谓的平衡数,就是以这个数字的某一位为支点,另外两边的数字大小乘以力矩之和相等,即为平衡数. 思路: 一开始以为需要枚举位数,枚举前缀和,枚举后缀和,一旦枚举起来就会M ...
- HDU3709 Balanced Number —— 数位DP
题目链接:https://vjudge.net/problem/HDU-3709 Balanced Number Time Limit: 10000/5000 MS (Java/Others) ...
随机推荐
- es6 中let与const的简析
1.let 它的作用类似于var,用来声明变量,但是所声明的变量,只在let命令所在的代码块内有效. if(true){ ; let b = ; } document.write(a); docume ...
- IOS开发之UISearchBar自定义外观
MySearchBar.h如下: @interface MySearchBar : UISearchBar - (void)layoutSubviews; @end MySearchBar.m如下 ...
- python selenium 获取对象输入的属性值
.get_attribute("value") from selenium import webdriver import time driver=webdriver.Firefo ...
- element表格多选实现单选
9.element多选表格实现单选 userChoose(selection, row) { console.log(selection,'selection') console.log(row,'r ...
- H3C 快速以太网和千兆以太网
- hdu 3339 In Action(迪杰斯特拉+01背包)
In Action Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total S ...
- SQL 变量,运算符
一.变量 SQL语言也跟其他编程语言一样,拥有变量.分支.循环等控制语句. 在SQL语言里面把变量分为局部变量和全局变量,全局变量又称系统变量. (一).局部变量 使用declare关键字给变量声明, ...
- 以P2P网贷为例互联网金融产品如何利用大数据做风控?
以P2P网贷为例互联网金融产品如何利用大数据做风控? 销售环节 了解客户申请意愿和申请信息的真实性:适用于信贷员模式. 风控关键点 亲见申请人,亲见申请人证件,亲见申请人签字,亲见申请人单位. 审 ...
- 如何将为Android开发的AIR应用转移到SD卡
如果你想用户能够将为Android开发的AIR应用转移到SD卡上,所需要做的是在你的应用程序描述符中修改一下.如果你想你的应用程序默认安装到内置存储器中,但是允许用户把它转移到SD卡上,设置andro ...
- 怎么让FOXMAIL关了以后在右下角自动收取邮件
1.缩小到任务栏:打开foxmail,在工具-系统设置-常规,选项中有一项最小化时在任务栏显示,勾选上即可.2.要自动收取邮件,选中邮件账户,右键打开菜单,属性-接收邮件,右边勾选上“每隔*分钟自动收 ...