目录
1.(题解传送门-待消化)Beautiful numbers CodeForces - 55D
2.【待完成】XHXJ's LIS HDU - 4352 :
4.(题解传送门-待消化!)Bomb HDU - 3555 :
5.(题解传送门)Round Numbers POJ - 3252 :
6.【题解传送门】Balanced Number HDU - 3709 :
7.(题解传送门-待消化)B-number HDU - 3652 :
8.(题解传送门-待总结)F(x) HDU - 4734 :
9.【待完成】BCD Code ZOJ - 3494 (数位DP+AC自动机):
10.(题解传送门)吉哥系列故事――恨7不成妻 HDU - 4507 :
11.(题解传送门)Balanced Numbers SPOJ - BALNUM :
写在前面:
这篇博客写的很随便,因为已经习惯了markdown,这种编辑方式真难受,水完了事,能看懂就行,排版就完全管了。
- 开始时间:2021-06-07
- 专题传送门:https://vjudge.net/article/187[kuangbin带你飞]专题1-23
- 首次接触数位DP,可以先了解一下它的形式,然后变刷题边思考其原理,最后刷完这个专题之后再总结提炼一下它的思想
博客:
- 我的总结:DP基础知识总结
- 难度判断: [kuangbin带你飞]专题十五 数位DP
- 带佬的总结:【数位dp】 Step by Step、[总结]数位统计模板
题目:
1.(题解传送门-待消化)Beautiful numbers CodeForces - 55D
- 题意:给定两个数l,r(1<=l<=r<=9e18),求[l,r]间漂亮数的个数(漂亮数:能被所有非0数位整除的数)
- 关键词:数位DP,模板
2.【待完成】XHXJ's LIS HDU - 4352 :
1. 题意题解参考博客:hdu_4352_XHXJ's LIS(数位DP+状态压缩)
2. 严格递增
3.(没有题解)不要62 HDU - 2089 :
- 题意:统计区间 [a,b] 中不含 4 和 62 的数字有多少个。(0<a<=b<=1e6)
- 题解:sb题,暴力
4.(题解传送门-待消化!)Bomb HDU - 3555 :
- 题意:给一个数n(1<=n<=2^63-1),然后求出1~n中49子数和(比如49249=2,490302=1)
- 关键词:数位DP,模板
5.(题解传送门)Round Numbers POJ - 3252 :
- 关键词:数位DP,前导0的处理
6.【题解传送门】Balanced Number HDU - 3709 :
- 提示:枚举中心点
- 关键词:枚举中心点,数位dp,好题
7.(题解传送门-待消化)B-number HDU - 3652 :
- 题意:找出1~n有多少个数既含有13又能被13整除。(1<=n<=1e9)
- 关键词:数位DP,模板,深搜DFS
8.(题解传送门-待总结)F(x) HDU - 4734 :
- 题意:定义数
,定义函数
,然后,给出一个区间 [A,B](0<=A,B<1e9),求区间 [0,B] 内满足F(i)<=F(A) 的 i 的个数。
多组输入(T<=10000)。 - 关键词:数位DP,模板题,数位DP总结1
9.【待完成】BCD Code ZOJ - 3494 (数位DP+AC自动机):
1. 涉及AC自动机,等学字符串的时候再来看这里吧
2. 题意参考:zoj 3494(ac自动机+数位dp)
10.(题解传送门)吉哥系列故事――恨7不成妻 HDU - 4507 :
- 题意:多组输入T<=50,每个区间[L,R]。1<=L<=R<=1e18
- 关键词:数位DP,dfs,进阶模板题
- 收获&总结:
11.(题解传送门)Balanced Numbers SPOJ - BALNUM :
- 关键词:数位DP+好题+排除前置0的干扰!!!!
平时训练遇到的数位DP
1. 2021暑假牛客多校第一场F题(数位DP,好题)
- 题意:求[L,R]内的友好数的个数,(1<=L<=R<=1e18)。
- 友好数的定义:把这个数看作字符串,存在非空子串表示的数能被3整除,那么这个数为友好数,否则不为友好数。
- 带有前导0的子字符串被认为是合法的。
- 题解:数位DP。
- 一些提示(因为懒得梳理):
- 首先找dp数组,dp[pos][last0][last1][last2],last0,1,2分别表示以pos数结尾的上一位是否有0,1,2的余数。
- 最后判断一个数,如果没有前导0而且last0=0的时候既表示友好数
- 如果已经!lead的时候last0为1,那么后面的last0都为1
- 具体看代码。总之注意多方面思考
- 代码:
#include <bits/stdc++.h>
#define int long long
#define dbg(x) cout << #x << "===" << x << endl
using namespace std;
int l, r;
int dp[22][2][2][2]; // dp[pos][last0][last1][last2]
int t[5];
int a[22], cnt;
//前导0无影响
int dfs(int pos, int k0, int k1, int k2, bool lead, bool limit) {
if (pos == -1) return k0 && (!lead);
if (!limit && !lead && dp[pos][k0][k1][k2] != -1)
return dp[pos][k0][k1][k2];
int res = 0;
int up = limit ? a[pos] : 9;
for (int i = 0; i <= up; i++) {
t[0] = t[1] = t[2] = 0;
t[(0 * 10 + i) % 3] = 1;
if (k1) t[(1 * 10 + i) % 3] = 1;
if (k2) t[(2 * 10 + i) % 3] = 1;
if (!lead && k0) t[0] = 1;
res += dfs(pos - 1, t[0], t[1], t[2], lead && (i == 0),
limit && (i == a[pos]));
}
if (!lead && !limit) dp[pos][k0][k1][k2] = res;
return res;
}
int solve(int x) {
cnt = 0;
while (x) {
a[cnt++] = x % 10;
x /= 10;
}
return dfs(cnt - 1, 0, 0, 0, true, true);
}
signed main() {
int T;
cin >> T;
memset(dp, -1, sizeof(dp));
while (T--) {
cin >> l >> r;
// dbg(solve(r));
// dbg(solve(l - 1));
int ans = solve(r) - solve(l - 1);
// cout << ">>>>";
cout << ans << endl;
}
return 0;
}
某次任务——数位dp分享
1. 收获很多啊。果然将知识讲出来效果最好。
总结:1.1 把数位DP整个过程看作遍历一棵树的过程。
1.2 dp[][]表示的是树上某一个节点能到达的满足条件的叶子节点的数。
1.3 从暴力到数位dp优化的是树上结点的数目,我们把同一层的点权相同的节点合并。
2. 详见我的ppt: 数位dp——某次队内分享任务
3. 理解这一颗树的过程: