数位DP小结

来源:互联网 发布:淘宝卖家开店的流程图 编辑:程序博客网 时间:2024/06/08 07:03


数位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 numint 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小的有多少个,那就满足所有的询问了,就只需要初始化一次。

具体看这

http://blog.csdn.net/nealgavin/article/details/11703049

/***********************************************************************************************/

然后:数位DP 最重要的就赛状态设计和,一些状态精简之类的问题了。

《1.》 像这一题就是和LCM有关的数位DP 。

CodeForces 55D Beautiful numbers (数位DP+状态简化,5级)

http://blog.csdn.net/nealgavin/article/details/10446739

很容易能想到三维DP dp[第几位][模上最小公倍数数的余数][最小公倍数]

          最小公倍数到2520 为止 ,故 需要 19x2520x2520 爆空间了。

         但实际上能取到的最小公倍数没有2520个,只要几十个,因此可以哈希一下,因为DP只要记录其不同状态就可以了。

        dp不需要每个数都算原因是不同数的mod数不同。因此不会错

         接下来,就是水数位DP了。

《2.》SPOJ 10606. Balanced Numbers (数位DP,4级)

http://blog.csdn.net/nealgavin/article/details/10335221

《3.》这道是好题。状态压缩的递增自序列数位DP ,如果都理解透的化也是可以秒的。

 

hdu 4352 XHXJ's LIS(LIS+数位DP,5级)


http://blog.csdn.net/nealgavin/article/details/10078027

《4.》这到题就需要理解数位DP,它到底在求的是什么。

hdu 3709 Balanced Number(数位DP,5级)

http://blog.csdn.net/nealgavin/article/details/10084467

《5.》好题,需要设计多种状态,要分清楚。 

hdu 4507 吉哥系列故事——恨7不成妻(数位DP,5级)

http://blog.csdn.net/nealgavin/article/details/10095879

思路:维护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级)


http://blog.csdn.net/nealgavin/article/details/10303521



原创粉丝点击