P6371 [COCI2006-2007#6] V 题解

一个比较有趣的数位 DP。

考虑当 XX 比较大的时候,可以暴力枚举 XX 的所有倍数,判断是否可行,这个的复杂度是 O(BX)O(\dfrac{B}{X}) 的。这个过程类似根号分治,当 X>LX>L 时暴力,我的做法中取 L=104L=10^4

对于 XLX \leq L,考虑数位 DP。平凡的,只需要在 DP 的时候记录当前的数对 XX 取模的结果即可。由于 X104X \leq 10^4,所以数组一定开得下。

有一点需要注意,如果 00 不能用,要注意前导 00 仍可以用。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
using namespace std;

const int LIM = 1e4;
const int N = 13;

long long x, a, b;
string s;
bool flag[N];

long long solve1()
{
	for (auto& i : s) flag[i - '0'] = 1;
	long long ans = 0LL;
	for (long long i = x; i <= b; i += x)
	{
		if (i < a) continue;
		string ss = to_string(i);
		for (auto& i : ss)
		{
			if (!flag[i - '0'])
			{
				goto E;
			}
		}
		ans++;
	E:;
	}
	return ans;
}

long long dp[N][LIM + 5][2][2];
string p;

long long dfs(int u, long long r, bool flag, bool zgw)
{
	if (~dp[u][r][flag][zgw]) return dp[u][r][flag][zgw];
	dp[u][r][flag][zgw] = 0;
	if (r == 0 && u == p.size())
	{
		if (!flag)
		{
			dp[u][r][flag][zgw] = 1;
		}
	}
	if (u > p.size() - 1) return dp[u][r][flag][zgw];
	int nowlim = (zgw ? p[u] - '0' : 9);
	for (auto& i : s)
	{
		int gg = i - '0';
		if (gg <= nowlim)
		{
			dp[u][r][flag][zgw] += dfs(u + 1, (r * 10LL + gg) % x, (flag && gg == 0), (zgw && gg == nowlim));
		}
	}
	if (flag && s.find("0") == -1)
	{
		dp[u][r][flag][zgw] += dfs(u + 1, 0LL, 1, 0);
	}
	return dp[u][r][flag][zgw];
}

long long solve2()
{
	p = to_string(b);
	p = " " + p;
	memset(dp, -1, sizeof dp);
	long long ans1 = dfs(1, 0, 1, 1);
	p.clear();
	p = to_string(a - 1);
	p = " " + p;
	memset(dp, -1, sizeof dp);
	long long ans2 = dfs(1, 0, 1, 1);
	return ans1 - ans2;
}

int main()
{
	ios::sync_with_stdio(0), cin.tie(0);
	cin >> x >> a >> b >> s;
	if (x > LIM) cout << solve1() << "\n";
	else cout << solve2() << "\n";
	return 0;
}
posted @   HappyBobb  阅读(5)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示