数位DP小结
2013-09-18 12:13
239 查看
数位DP递归版的基本模式。
数位DP经常询问的是在某个区间内符合某种条件的个数。
我个人喜欢用递归,因为简单好些。
先给个基本模式。
hdu 2089 不要62
http://acm.hdu.edu.cn/showproblem.php?pid=2089
询问区间中不包含4和62的个数。
大体的数位DP 都可以套用以上的形式来写。
其中状态有个注意点,就是设计的DP 状态能不能适用于所有的分组数据,如果可以就只需要初始化一次,如果不行,那每次执行都需要初始化。
比如:
DP,4级)
如果设计状态是dp[bit][statue] 表示i位长,能达到值为statue 的最优值,那就得每次初始化,那就T 了,因为每次询问所要求小于的数都不一样。
但如果换一个表式就可以了,表示bit位长,比statue小的有多少个,那就满足所有的询问了,就只需要初始化一次。
具体看这
/article/8106346.html
/***********************************************************************************************/
然后:数位DP 最重要的就赛状态设计和,一些状态精简之类的问题了。
《1.》 像这一题就是和LCM有关的数位DP 。
CodeForces 55D Beautiful numbers (数位DP+状态简化,5级)
/article/8106301.html
很容易能想到三维DP dp[第几位][模上最小公倍数数的余数][最小公倍数]
最小公倍数到2520 为止 ,故 需要 19x2520x2520 爆空间了。
但实际上能取到的最小公倍数没有2520个,只要几十个,因此可以哈希一下,因为DP只要记录其不同状态就可以了。
dp不需要每个数都算原因是不同数的mod数不同。因此不会错
接下来,就是水数位DP了。
《2.》SPOJ 10606. Balanced Numbers (数位DP,4级)
/article/8106297.html
《3.》这道是好题。状态压缩的递增自序列数位DP ,如果都理解透的化也是可以秒的。
《4.》这到题就需要理解数位DP,它到底在求的是什么。
hdu 3709 Balanced Number(数位DP,5级)
/article/8106292.html
《5.》好题,需要设计多种状态,要分清楚。
/article/8106293.html
思路:维护3个值,个数,总和,平方和。
第一个是与7无关的数的个数,就是简单的数位DP了,很常规
第二个与7无关的数的和的维护需要用到第一个个数。
处理到第pos个数位时,加上i*10^pos * 后面的个数
第三个的维护需要用到前面两个
(pre*10^pos + next)^2= (pre*10^pos)^2+2*pre*10^pos*next +next^2
《6.》同样是道好题,AC自动机+数位DP 。要先用AC自动机先预处理出所有的转移态,然后数位DP 转移态
数位DP经常询问的是在某个区间内符合某种条件的个数。
我个人喜欢用递归,因为简单好些。
先给个基本模式。
hdu 2089 不要62
http://acm.hdu.edu.cn/showproblem.php?pid=2089
询问区间中不包含4和62的个数。
#include<cstring> #include<cstdio> #include<iostream> #define FOR(i,a,b) for(int i=a;i<=b;++i) #define clr(f,z) memset(f,z,sizeof(f)) using namespace std; const int mm=11; int dp[mm][mm][2];///位数,last num,has contain bad num int bit[mm]; int DP(int pp,int last,bool has,bool big) { if(pp==-1)return has==0;///no contain bad num if(big&&dp[pp][last][has]!=-1)return dp[pp][last][has]; int ret=0; int kn=big?9:bit[pp]; FOR(i,0,kn) { ret+=DP(pp-1,i,has||(i==4||(last==6&&i==2)),big||kn!=i); } if(big)dp[pp][last][has]=ret; return ret; } int get(int x) { int pos=-1; while(x) { bit[++pos]=x%10;x/=10; } return DP(pos,0,0,0); } int main() { clr(dp,-1); int n,m; while(cin>>n>>m) { if(n==0&&m==0)break; cout<<get(m)-get(n-1)<<endl; } }
大体的数位DP 都可以套用以上的形式来写。
其中状态有个注意点,就是设计的DP 状态能不能适用于所有的分组数据,如果可以就只需要初始化一次,如果不行,那每次执行都需要初始化。
比如:
hdu 4734 F(x)(数位
DP,4级)如果设计状态是dp[bit][statue] 表示i位长,能达到值为statue 的最优值,那就得每次初始化,那就T 了,因为每次询问所要求小于的数都不一样。
但如果换一个表式就可以了,表示bit位长,比statue小的有多少个,那就满足所有的询问了,就只需要初始化一次。
具体看这
/article/8106346.html
/***********************************************************************************************/
然后:数位DP 最重要的就赛状态设计和,一些状态精简之类的问题了。
《1.》 像这一题就是和LCM有关的数位DP 。
CodeForces 55D Beautiful numbers (数位DP+状态简化,5级)
/article/8106301.html
很容易能想到三维DP dp[第几位][模上最小公倍数数的余数][最小公倍数]
最小公倍数到2520 为止 ,故 需要 19x2520x2520 爆空间了。
但实际上能取到的最小公倍数没有2520个,只要几十个,因此可以哈希一下,因为DP只要记录其不同状态就可以了。
dp不需要每个数都算原因是不同数的mod数不同。因此不会错
接下来,就是水数位DP了。
《2.》SPOJ 10606. Balanced Numbers (数位DP,4级)
/article/8106297.html
《3.》这道是好题。状态压缩的递增自序列数位DP ,如果都理解透的化也是可以秒的。
hdu 4352 XHXJ's LIS(LIS+数位DP,5级)
/article/8106291.html
《4.》这到题就需要理解数位DP,它到底在求的是什么。hdu 3709 Balanced Number(数位DP,5级)
/article/8106292.html
《5.》好题,需要设计多种状态,要分清楚。
hdu 4507 吉哥系列故事——恨7不成妻(数位DP,5级)
/article/8106293.html思路:维护3个值,个数,总和,平方和。
第一个是与7无关的数的个数,就是简单的数位DP了,很常规
第二个与7无关的数的和的维护需要用到第一个个数。
处理到第pos个数位时,加上i*10^pos * 后面的个数
第三个的维护需要用到前面两个
(pre*10^pos + next)^2= (pre*10^pos)^2+2*pre*10^pos*next +next^2
《6.》同样是道好题,AC自动机+数位DP 。要先用AC自动机先预处理出所有的转移态,然后数位DP 转移态
ZOJ 3494 BCD Code (AC自动机+数位DP,5级)
/article/8106296.html
相关文章推荐
- 基础数位DP小结
- 数位dp小结
- 数位DP小结
- 数位DP专题小结--by sgx
- 数位dp_小结
- 数位dp小结
- 数位DP小结_记忆化搜索版
- 数位dp小结(状压的第一次试水)
- 【算法笔记】数位dp小结
- 数位DP小结
- 数位DP小结(阶段性)
- 数位DP专题小结--by sgx 数位DP专题小结--by sgx
- Timus 1057 数位dp
- hdu 4734 F(x) 数位dp
- 2017.10.20(积性函数,BSGS,K进制数位DP)
- 【bzoj1833】[ZJOI2010]count 数字计数 数位DP
- hdu 2089(初学数位DP)
- 数位DP进阶-HDU2089不要62
- [数位DP Lucas定理] 2017 计蒜之道 复赛 E. 商汤智能机器人
- 1026:[SCOI2009]windy数 (数位DP)