数位dp专题之Beautiful numbers

Posted yeah17981

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数位dp专题之Beautiful numbers相关的知识,希望对你有一定的参考价值。

持续更新中……

Problem - D - Codeforces

Beautiful numbers

数位dp之dp手的折戟

我真的好讨厌写dfs啊

dp?dfs!

幸好还是做出了一道,不然就真罚座一晚上了。

给t组查询,求l到r之间有多少个数字,满足其每一位数都是其因子

首先找到1-9的最小公倍数为2520,它的48个因子分别对应的是1-9不同组合下的最小公倍数。通过离散化把48个因子标序1-48

再者,因为需要进行状态的转移,在记录数字铁定会爆的情况下我们选择记录对2520取模后的结果,通过对余数的处理进行转移。

看这数字肯定不能暴力捏,但是结果和位数存在关系,考虑枚举位数,并且记录此时是否达到上限。

而余数*10+位数可能性为新的余数,由此进行动态转移

设dp[j][i][k],当前位为j,余数为i,最小公倍数ak下的ans

dfs(pos,presum,prelcm,flag) 分别为 当前位数,当前余数,当前lcm,是否达到上限       

其余的看看代码吧

//给n个范围,求区间内符合条件的元素个数
//如果是2520的倍数一符合条件 如果不是,看余数 
//dp[j][i][k] 当前位为j,余数为i,最小公倍数ak下的ans


#include<bits/stdc++.h> 
using namespace std;

const long long mod=2520;
long long a[mod];
long long num1[25];
long long dp[10][2520][48];
void _init_()//预处理出所有因数和id的关系
	long long cnt=0;
	for(long long i=1;i<=mod;i++)
	
		if(mod%i==0) a[i]=cnt++;
	

long long lcm(long long a,long long b)//求lcm

	return a/__gcd(a,b)*b;

long long dfs(long long pos,long long presum,long long prelcm,bool flag)//从高位向低位枚举

	if(pos==-1) return presum%prelcm==0;//所有位数都枚举过了
	if(!flag&&dp[pos][presum][a[prelcm]]!=-1)//已达上限且已经算过了
		return dp[pos][presum][a[prelcm]];
	long long ans=0;
	long long end = flag ? num1[pos] : 9;//没到上限就取上限,到了就取9
    for (long long i = 0; i <= end; i++) 
        long long nowSum = (presum * 10 + i) % mod;//处理余数
        long long nowLcm = prelcm;
        if (i) 
            nowLcm = lcm(nowLcm, i);//更新lcm
        
        ans += dfs(pos - 1, nowSum, nowLcm, flag && i == end);
    
    if (!flag) //已达上限但是没算过
        dp[pos][presum][a[prelcm]] = ans;
    
    return ans;

long long calc(long long x)

	long long cnt=0,n=x;
	while(n>0)
	
		num1[cnt++]=n%10; 
		n/=10;
	
	return dfs(cnt-1,0,1,1);

int main()

	_init_();
	  memset(dp, -1, sizeof(dp)); 	
	long long _,l,r;
	cin>>_;
	while(_--)
	
		
		cin>>l>>r;
		cout<<calc(r)-calc(l-1)<<"\\n";
	


大致就这样吧我困了我真的不会我要去吃夜宵了qaq

以上是关于数位dp专题之Beautiful numbers的主要内容,如果未能解决你的问题,请参考以下文章

CodeForces 55D Beautiful numbers(数位dp&&离散化)

5179 beautiful number(数位dp)

CodeForces - 55D Beautiful numbers (数位DP)

CodeForces 55D - Beautiful numbers - [数位DP+离散化]

[暑假集训--数位dp]cf55D Beautiful numbers

beautiful number 数位dp