[CodeForces 55D] Beautiful numbers && 数位DP

凡是大于3维的状态我都莫名的想用记忆化省去一维 写法一样

注意要离散化LCM值 不然数组开不下 而且CF还报一个奇怪的错 看了我好久

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
using namespace std;
typedef long long LL;
const int MAXL = 2520;
const int MAXN = 30;
LL d[MAXN+10][MAXL+10][60];
int bit[MAXN+10], Num[MAXL+10], Goback[MAXL+10], cnt;
int gcd(int x, int y)
{
	while(y)
	{
		int r = x % y;
		x = y;
		y = r;
	}
	return x;
}
LL dp(int h, int sum, int lcm, bool limit)
{
	if(h == 0) return (sum % Num[lcm]) ? 0 : 1;
	if(d[h][sum][lcm] != -1 && !limit) return d[h][sum][lcm];
	lcm = Num[lcm];
	LL ans = 0;
	int ed = limit ? bit[h] : 9;
	for(int i = 0; i <= ed; i++)
	{
		int Newlcm;
		if(i == 0) Newlcm = lcm;
		else Newlcm = lcm / gcd(lcm, i) * i;
		ans += dp(h-1, (sum * 10 + i) % MAXL, Goback[Newlcm], limit && i == ed);
	}
	if(!limit) d[h][sum][Goback[lcm]] = ans;
	return ans;
}
LL solve(LL X)
{
	int Len = 0;
	memset(bit, 0, sizeof(bit));
	while(X) {
		bit[++Len] = X % 10;
		X /= 10;
	}
	return dp(Len, 0, 1, 1);
}
void init()
{
	cnt = 0;
	memset(d, -1, sizeof(d));
	for(int i = 1; i <= MAXL; i++)
		if(!(MAXL % i))
			Num[++cnt] = i, Goback[i] = cnt;
}
int main()
{
	init();
	int T; scanf("%d", &T); while(T--) 
	{
		LL L, R;
		cin >> L >> R;
		LL ans = solve(R) - solve(L-1);
		cout << ans << '\n';
	}
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值