BZOJ 4521 CQOI2016 手机号码 数位dp
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4521
题意概述:给出一个区间[L,R],统计区间中满足:1、4,8不同时出现;2、至少有3个相邻的相同数字 的数字个数。10^10<=L<R<10^11.
实际上要想个状态方程和转移很好想,只是细节和答案就有点。。。。
简单来说,设f(i,x,y,0/1/2,0/1)表示第i位上的数是x,第i-1位上的数是y,4,8没有出现过 / 4出现过 / 8出现过,有/无三个相邻的相同数字的数字数量。
转移的时候f(1,x,y,0/1/2,0/1)可以直接暴力初始化,然后转移过程中对方程后两个位置上的状态讨论即可(分为之前就是这样和之前不是这样但是这一步变成了这样两种)。
计算答案的时候从高到低考虑,同时注意当前确定下来的数里面4,8出现的情况以及有无相邻的三个数字,以加上限制或者增加更新范围。
最后说一点建议L那个位置特判一下否则很惨。。。。
然后循环的时候上界不要写错了,不要脑子不知道发生了什么把10写成了9之类的耗掉了1h,不要问我怎么知道的!!!!!
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<algorithm> 6 #include<cmath> 7 #include<queue> 8 #include<set> 9 #include<map> 10 #include<vector> 11 #include<cctype> 12 using namespace std; 13 typedef long long LL; 14 15 LL L,R,f[13][10][10][3][2]; 16 17 void dp() 18 { 19 for(int x=0;x<10;x++) 20 for(int y=0;y<10;y++){ 21 f[1][x][y][0][0]=x!=4&&x!=8&&y!=4&&y!=8?1:0; 22 f[1][x][y][1][0]=(x==4||y==4)&&x!=8&&y!=8?1:0; 23 f[1][x][y][2][0]=(x==8||y==8)&&x!=4&&y!=4?1:0; 24 } 25 for(int i=2;i<=10;i++) 26 for(int x=0;x<10;x++){ 27 for(int y=0;y<10;y++) 28 for(int z=0;z<10;z++){ 29 if(x!=4&&x!=8&&(x!=y||x!=z)) f[i][x][y][0][0]+=f[i-1][y][z][0][0]; 30 if(x!=8&&(x!=y||x!=z)) f[i][x][y][1][0]+=f[i-1][y][z][1][0]; 31 if(x==4&&(x!=y||x!=z)) f[i][x][y][1][0]+=f[i-1][y][z][0][0]; 32 if(x!=4&&(x!=y||x!=z)) f[i][x][y][2][0]+=f[i-1][y][z][2][0]; 33 if(x==8&&(x!=y||x!=z)) f[i][x][y][2][0]+=f[i-1][y][z][0][0]; 34 if(x!=4&&x!=8) f[i][x][y][0][1]+=f[i-1][y][z][0][1]; 35 if(x!=8) f[i][x][y][1][1]+=f[i-1][y][z][1][1]; 36 if(x==4) f[i][x][y][1][1]+=f[i-1][y][z][0][1]; 37 if(x!=4) f[i][x][y][2][1]+=f[i-1][y][z][2][1]; 38 if(x==8) f[i][x][y][2][1]+=f[i-1][y][z][0][1]; 39 } 40 if(x!=4&&x!=8) f[i][x][x][0][1]+=f[i-1][x][x][0][0]; 41 if(x!=8) f[i][x][x][1][1]+=f[i-1][x][x][1][0]; 42 if(x!=4) f[i][x][x][2][1]+=f[i-1][x][x][2][0]; 43 } 44 } 45 LL calc(LL A) 46 { 47 int n[15]={0},cnt=0; 48 n[cnt++]=A%10,A/=10; 49 while(A) n[cnt++]=A%10,A/=10; 50 LL re=0; 51 for(int x=1;x<n[10];x++) 52 for(int y=0;y<10;y++) 53 re+=f[10][x][y][0][1]+f[10][x][y][1][1]+f[10][x][y][2][1]; 54 int x=n[10]; 55 int ok=0,p4=x==4,p8=x==8; 56 for(int i=10;i>=1;i--){ 57 for(int y=0;y<n[i-1]+(i==1);y++){ 58 if(y==4&&p8||y==8&&p4) continue; 59 re+=f[i][x][y][0][1]; 60 if(!p8) re+=f[i][x][y][1][1]; 61 if(!p4) re+=f[i][x][y][2][1]; 62 if(ok||x==y&&x==n[i+1]){ 63 re+=f[i][x][y][0][0]; 64 if(!p8) re+=f[i][x][y][1][0]; 65 if(!p4) re+=f[i][x][y][2][0]; 66 } 67 } 68 x=n[i-1],p4|=(x==4),p8|=(x==8); 69 if(n[i-1]==n[i]&&n[i]==n[i+1]) ok=1; 70 if(p4&&p8) break; 71 } 72 return re; 73 } 74 int check(LL x) 75 { 76 int n[15]={0},cnt=0,p4=0,p8=0,ok=0; 77 n[cnt++]=x%10,x/=10; 78 while(x) n[cnt++]=x%10,x/=10; 79 for(int i=0;i<cnt;i++){ 80 p4|=n[i]==4,p8|=n[i]==8; 81 if(p4&&p8) return 0; 82 if(i>1&&n[i]==n[i-1]&&n[i]==n[i-2]) ok=1; 83 } 84 return ok; 85 } 86 int main() 87 { 88 cin>>L>>R; 89 dp(); 90 cout<<calc(R)-calc(L)+check(L)<<'\n'; 91 return 0; 92 }
转载于:https://www.cnblogs.com/KKKorange/p/8562653.html
BZOJ 4521 CQOI2016 手机号码 数位dp相关推荐
- [CQOI2016]手机号码 数位DP
[CQOI2016]手机号码 用来数位DP入门,数位DP把当前是否需要限制取数范围(是否正在贴着临界值跑,即下面的limited)和一切需要满足的条件全部塞进记忆化搜索参数里面就好了,具体情况转移便好 ...
- bzoj 4521 [ Cqoi 2016 ] 手机号码 —— 数位DP
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4521 数位DP,记录好多维状态: 写了半天,复杂得写不下去了,于是参考一下TJ... 练习简 ...
- Bzoj 3652: 大新闻(数位dp)
以下内容来自ShallWe's Blog 题目 3652: 大新闻 Description Input Output \(1<=N<=10^18\) 解题报告 显然是一道数位dp的题目,观 ...
- BZOJ 1026 windy数 (数位DP)
题意 区间[A,B]上,总共有多少个不含前导零且相邻两个数字之差至少为2的正整数? 思路 状态设计非常简单,只需要pos.limit和一个前驱数pre就可以了,每次枚举当前位时判断是否与上一位相差2即 ...
- 【洛谷P4124】[CQOI2016]手机号码
手机号码 数位DP模板题 记忆化搜索: #include<iostream> #include<cstring> #include<cstdio> using na ...
- [SOCI2005]最大子矩阵(DP) + [JXOI2018]守卫(DP) + [CQOI2016]手机号码(数位DP)[各种DP专练]
DP专练博客 DP专练 T1:最大子矩阵 题目 题解 代码实现 T2:守卫 题目 题解 代码实现 T3:手机号码 题目 题解 代码实现 T1:最大子矩阵 题目 这里有一个n*m的矩阵,请你选出其中k个 ...
- [BZOJ4521][Cqoi2016]手机号码 (数位dp)
题目描述 人们选择手机号码时都希望号码好记.吉利.比如号码中含有几位相邻的相同数字.不含谐音不吉利的数字等.手机运营商在发行新号码时也会考虑这些因素,从号段中选取含有某些特征的号码单独出售.为了便于前 ...
- BZOJ 1799 [Ahoi2009] self 同类分布(数位DP)【BZOJ千题计划(quexin】
整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 题目链接 https://hydro.ac/d/bzoj/p/1799(样例时限设置有问题,应该为 2 ...
- BZOJ 3329 Xorequ (数位DP、矩阵乘法)
BZOJ 3329 Xorequ (数位DP.矩阵乘法) 手动博客搬家: 本文发表于20181105 23:18:54, 原地址https://blog.csdn.net/suncongbo/arti ...
最新文章
- php zblog 侧边栏样式_zblogphp版如何实现导航栏下拉框
- (面试)java基础-String一些特性
- html研究中心,seo研究中心 教程:认识HTML、css的重要性-专业SEO技
- 复习--3--对于第三堂课的总结--将两个页面相互用超链接链接到一起
- Android调试秘钥证书指纹获取方式
- js中var、let、const区别
- 业务逻辑 : forex mlm
- Oracle的Net Configuration Assistant 配置
- PHP之常用设计模式
- [转载] python中append函数的用法
- pivot position_PIVOT用法详解
- 串口波形显示软件SerialChart的使用
- 面试官:聊聊二维码扫码登录的原理
- win10共享计算机时用户名和密码错误,win10系统共享文件密码错误的解决方法
- 【FACT】函数使用技巧
- 结构光三维重建(二)线结构光三维重建
- 瘟神的尾行 -- Rootkit技术发展史 (转载)
- 图解Word2vec
- Android设备与外接U盘实现数据读取操作
- 玩一玩Spring容器(可视化笔记02)
热门文章
- phpBB安装环境配置
- [PCB]PCB设计尾声-焊盘泪滴与铺铜设计的作用与具体操作
- Flutter 倒计时功能
- R语言计算31省份(除港澳台地区)省会城市的球面距离代码
- 关于当代宜兴方言若干问题的讨论(3)_拔剑-浆糊的传说_新浪博客
- python模拟春节集五福_用Python分析支付宝红包和2018年集五福活动,你准备好了吗?...
- 艾司博讯:拼多多怎样算延迟发货?
- webpack2--tidying up
- 抖音python广告用的什么音乐_抖音上那些魔性洗脑神曲音乐,我用Python教你一次性下载...
- Linux之RPM包的安装、升级与卸载命令