【luogu4124】【bzoj4521】 [CQOI2016]手机号码 [数位dp]

P4124 [CQOI2016]手机号码

4521

这道题要注意卡上下界

我错了 写dfs版的更好考虑状态 写纯方程转移那个细节把我想瓜了

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<queue>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<stack>
 7 #include<algorithm>
 8 using namespace std;
 9 #define ll long long
10 #define rg register
11 const int N=2000000000+5,inf=0x3f3f3f3f,P=19650827;
12 ll a,b;
13 ll base[20],f[15][10][10][2][2][2];
14 ll num[20];
15 template <class t>void rd(t &x)
16 {
17     x=0;int w=0;char ch=0;
18     while(!isdigit(ch)) w|=ch==‘-‘,ch=getchar();
19     while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
20     x=w?-x:x;
21 }
22
23 ll dfs(int pos,int pre,int prr,int h4,int h8,int h,bool dlimi,bool ulimi){
24     if(!pos) return h?1:0;
25     if(!ulimi&&!dlimi&&pre+1&&prr+1&&f[pos][pre][prr][h4][h8][h])
26     return f[pos][pre][prr][h4][h8][h];
27     int up=ulimi?num[pos]:9,dw=dlimi?1:0;
28     ll ans=0;
29     for(int i=dw;i<=up;++i){
30         if(h4&&i==8) continue;
31         if(h8&&i==4) continue;
32         ans+=dfs(pos-1,i,pre,h4||(i==4),h8||(i==8),h||(pre==prr&&prr==i),0,ulimi&&(i==num[pos]));
33     }
34     if(!ulimi&&!dlimi&&pre+1&&prr+1) f[pos][pre][prr][h4][h8][h]=ans;
35     return ans;
36 }
37 ll solve(ll x){
38     int p=0;
39     memset(num,0,sizeof(num));
40     while(x) num[++p]=x%10,x/=10;
41     return p!=11?0:dfs(p,-1,-1,0,0,0,1,1);
42 }
43
44 int main()
45 {
46     rd(a),rd(b);
47     //memset(f,-1,sizeof(f));
48     printf("%lld",solve(b)-solve(a-1));
49     return 0;
50 }

原文地址:https://www.cnblogs.com/lxyyyy/p/11000204.html

时间: 2024-10-28 17:36:10

【luogu4124】【bzoj4521】 [CQOI2016]手机号码 [数位dp]的相关文章

【BZOJ-4521】手机号码 数位DP

4521: [Cqoi2016]手机号码 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 303  Solved: 194[Submit][Status][Discuss] Description 人们选择手机号码时都希望号码好记.吉利.比如号码中含有几位相邻的相同数字.不含谐音不吉利的数字等.手机运营商在发行新号码时也会考虑这些因素,从号段中选取含有某些特征的号码单独出售.为了便于前期规划,运营商希望开发一个工具来自动统计号段中满足特征的号码数量

【题解】Luogu P4121 [CQOI2016]手机号码 数位DP

题目传送门 Solution 这里我采用记忆化搜索的形式实现有哪个大佬可以教教我递推板的数位dp啊 搜索的过程中记录是否曾出现8,是否曾出现4,是否曾有连续3个相同数字,搜到底返回就可以了 其实没有太多好写的,数位DP很多都是套模板 那还写来干嘛? 这道题 从$1e10$开始算! 从$1e10$开始算! 从$1e10$开始算! 这就意味着我们需要特殊处理最高位,而不是像普通的数位DP那样直接把最高位也丢进搜索里搜. 惨痛的70分教训大概只有我是这么蠢了嘤嘤嘤 Code #include <cst

4521: [Cqoi2016]手机号码|数位DP

数据范围这么小..感觉暴力可过啊.. DP也是随便设计状态 F[i][j][k][s][l] 表示前i位,最后一位是j 最后一位连续出现k次(如果k已经等于3那么就一直不变)s表示4,8的出现状态 l表示前缀是否和原数的前缀相同 转移就是枚举下一位转移,也很简单.. #include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio>

BZOJ 4521 CQOI 2016 手机号码 数位DP

4521: [Cqoi2016]手机号码 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 539  Solved: 325[Submit][Status][Discuss] Description 人们选择手机号码时都希望号码好记.吉利.比如号码中含有几位相邻的相同数字.不含谐音不 吉利的数字等.手机运营商在发行新号码时也会考虑这些因素,从号段中选取含有某些特征的号 码单独出售.为了便于前期规划,运营商希望开发一个工具来自动统计号段中满足特征的号码

Bzoj4521 [Cqoi2016]手机号码

Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 557  Solved: 335 Description 人们选择手机号码时都希望号码好记.吉利.比如号码中含有几位相邻的相同数字.不含谐音不 吉利的数字等.手机运营商在发行新号码时也会考虑这些因素,从号段中选取含有某些特征的号 码单独出售.为了便于前期规划,运营商希望开发一个工具来自动统计号段中满足特征的号码数 量. 工具需要检测的号码特征有两个:号码中要出现至少3个相邻的相同数字,号码中不能同 时

数位DP复习小结

之前学数位dp的时候底子没打扎实 虚的要死 这次正好有时间……刷了刷之前没做的题目 感觉自己脑洞不太够……比较经典的题或者见过的类似模型就能自己推出来,但是没有见过的模型就虚的要死(比如二进制数位DP) 感谢WQ的帮助,让我对数位DP的理解逐渐加深 那么我们总结一下这次做的题目…… bzoj4521 记忆化搜索即可,水爆 1 #include <cstring> 2 #include <cstdio> 3 using namespace std; 4 #define RG regi

P4124 [CQOI2016]手机号码

链接:https://www.luogu.org/problemnew/show/P4124 题目描述 人们选择手机号码时都希望号码好记.吉利.比如号码中含有几位相邻的相同数字.不含谐音不吉利的数字等.手机运营商在发行新号码时也会考虑这些因素,从号段中选取含有某些特征的号码单独出售.为了便于前期规划,运营商希望开发一个工具来自动统计号段中满足特征的号码数量. 工具需要检测的号码特征有两个:号码中要出现至少 33 个相邻的相同数字:号码中不能同时出现 88 和 44 .号码必须同时包含两个特征才满

【luoguP4124 】[CQOI2016]手机号码

题目描述 人们选择手机号码时都希望号码好记.吉利.比如号码中含有几位相邻的相同数字.不含谐音不吉利的数字等.手机运营商在发行新号码时也会考虑这些因素,从号段中选取含有某些特征的号码单独出售.为了便于前期规划,运营商希望开发一个工具来自动统计号段中满足特征的号码数量. 工具需要检测的号码特征有两个:号码中要出现至少 3 个相邻的相同数字:号码中不能同时出现 8 和 4.号码必须同时包含两个特征才满足条件.满足条件的号码例如:13000988721.23333333333.14444101000.而

51Nod 1009 数字1的个数 | 数位DP

题意: 小于等于n的所有数中1的出现次数 分析: 数位DP 预处理dp[i][j]存 从1~以j开头的i位数中有几个1,那么转移方程为: if(j == 1) dp[i][j] = dp[i-1][9]*2+pow(10,i-1);else dp[i][j] = dp[i-1][9]+dp[i][j-1]; 然后注意下对于每个询问统计的时候如果当前位为1需要额外加上他后面所有位数的个数,就是n%pow(10,i-1); 这样总复杂度log(n)*10 #include <bits/stdc++.