HDU5179 beautiful number 题解 数位DP
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5179
题目大意:
给你一个数 \(A = a_1a_2 \cdots a_n\) ,我们称 \(A\) 为“漂亮的数”当且仅当 \(a[i] \ge a[i+1]\) (\(1 \le i \lt n\)) 并且 \(a[i]\) mod \(a[j] = 0\) (\(1 \le i \lt n, i \lt j \le n\)),比如 \(931\) 就是一个漂亮的数。
求区间 \([L,R]\) 范围内有多少“漂亮的数”。
问题分析:
本题使用 数位DP 解决。
首先,要注意一个条件:
- 对于任意 \(i \lt j\) ,\(a[i]\) mod \(a[j] = 0\)
这其实等同于对于任意满足条件 \(i \le k \lt j\) 的 \(k\) ,\(a[k]\) mod \(a[k+1] = 0\) 。
即:对于当前位置 \(pos\) ,它的前一位要么一直都是 \(0\) ,要么 \(a[pos+1]\) (即 \(pos\) 位的高一位)能被 \(a[pos]\) 整除。
我们可以开函数 dfs(int pos, int pre, bool limit) 来解决这个问题,其中:
pos表示当前所处的数位;pre表示前一位的数值;limit表示当前是否处于限制状态。
实现代码如下:
#include <bits/stdc++.h>
using namespace std;
int f[33][10], a[33];
void init() {
memset(f, -1, sizeof(f));
}
int dfs(int pos, int pre, bool limit) {
if (pos < 0) return 1;
if (!limit && f[pos][pre] != -1) return f[pos][pre];
int up = limit ? a[pos] : 9;
int down = pre ? 1 : 0;
int tmp = 0;
for (int i = down; i <= up; i ++) {
if (pre && pre % i) continue;
tmp += dfs(pos-1, i, limit && i==up);
}
if (!limit) f[pos][pre] = tmp;
return tmp;
}
int get_num(int x) {
int pos = 0;
while (x) {
a[pos++] = x % 10;
x /= 10;
}
return dfs(pos-1, 0, true);
}
int T, L, R;
int main() {
init();
scanf("%d", &T);
while (T --) {
scanf("%d%d", &L, &R);
printf("%d\n", get_num(R)-get_num(L-1));
}
return 0;
}
HDU5179 beautiful number 题解 数位DP的更多相关文章
- HDU 5179 beautiful number (数位dp / 暴力打表 / dfs)
beautiful number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- hdu 5179 beautiful number(数位dp)
原题链接 题意:求[l,r]中高位%低位等于0的数字个数.(不含0)分析:此题有三种方法.1.暴搜,毕竟最多才10个位.2.数位dp,预处理好整体的,再处理细节. dp[i][j]表示第i位上的数字位 ...
- HDU3709 Balanced Number 题解 数位DP
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3709 题目大意: 求区间 \([x, y]\) 范围内"平衡数"的数量. 所谓平衡 ...
- HDU 3565 Bi-peak Number(数位DP)题解
题意:我们定义每一位先严格递增(第一位不为0)后严格递减的数为峰(比如1231),一个数由两个峰组成称为双峰,一个双峰的价值为每一位位数和,问L~R双峰最大价值 思路:数位DP.显然这个问题和pos有 ...
- HDU 3709 Balanced Number(数位DP)题解
思路: 之前想直接开左右两边的数结果爆内存... 枚举每次pivot的位置,然后数位DP,如果sum<0返回0,因为已经小于零说明已经到了pivot右边,继续dfs只会越来越小,且dp数组会炸 ...
- Codeforces 55D Beautiful Number (数位统计)
把数位dp写成记忆化搜索的形式,方法很赞,代码量少了很多. 下面为转载内容: a positive integer number is beautiful if and only if it is ...
- HDU 5787 K-wolf Number (数位DP)
K-wolf Number 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5787 Description Alice thinks an integ ...
- CF 55D Beautiful numbers (数位DP)
题意: 如果一个正整数能被其所有位上的数字整除,则称其为Beautiful number,问区间[L,R]共有多少个Beautiful number?(1<=L<=R<=9*1018 ...
- HDU3709 Balanced Number (数位dp)
Balanced Number Time Limit:3000MS Memory Limit:0KB 64bit IO Format:%lld & %llu Descript ...
随机推荐
- oracle函数 current_timestamp
[功能]:以timestamp with time zone数据类型返回当前会话时区中的当前日期 [参数]:没有参数,没有括号 [返回]:日期 [示例]select current_timestamp ...
- uni-app原生导航栏使用iconfont图标
在 iconfont 将图标下载之后,会有一个 .ttf 后缀的文件 把它放进 static 文件夹里 然后打开在iconfont下载的 demo_index.html 文件 选择 Unicode ...
- C. Tokitsukaze and Duel 前缀维护
枚举每一个连续的K的第一个位置,如果是先手胜利,那么前[1 , i-1 ]和[ i+k , n ]区间要么全是0,要么全是1 如果能够平局,那么肯定是[1,i-1],以及[ i+k , n]中有两种情 ...
- poj 2451 Uyuw's Concert (半平面交)
2451 -- Uyuw's Concert 继续半平面交,这还是简单的半平面交求面积,不过输入用cin超时了一次. 代码如下: #include <cstdio> #include &l ...
- SuperSocket通过 SessionID 获取 Session
前面提到过,如果你获取了连接的 Session 实例,你就可以通过 "Send()" 方法向客户端发送数据.但是在某些情况下,你无法直接获取 Session 实例. SuperSo ...
- Codeforces Round #168 (Div. 1 + Div. 2)
A. Lights Out 模拟. B. Convex Shape 考虑每个黑色格子作为起点,拐弯次数为0的格子构成十字形,拐弯1次的则是从这些格子出发直走达到的点,显然需要遍历到所有黑色黑色格子. ...
- dotnet core 2.1 使用阶梯编译
在 dotnet core 2.1 可以使用阶梯编译的方法,从 dotnet framework 开始,在代码的所有方法在第一次进入的时候就需要使用 JIT 进行编译为本机的代码.可以看到代码是在第一 ...
- SVN中如何执行clean up
在要清理的文件夹上点右键,菜单:TortoiseSVN--选择cleanup,会出现一个菜单栏,在你菜单栏有一个属性breaklock意思是打破锁定,你勾选打破锁定,然后cleanup就会成功,之后再 ...
- InetAddress与Socket
InetAddress:构造方法私有,不能直接创建对象. InetAddress getByName(String host):在给定主机名的情况下确定主机的ip地址. InetAddress get ...
- linux一个例子驱动
我们介绍的驱动称为 short (Simple Hardware Operations and Raw Tests). 所有它做 的是读和写几个 8-位 端口, 从你在加载时选择的开始. 缺省地, 它 ...