IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 算法竞赛进阶指南- 月之谜 -> 正文阅读

[数据结构与算法]算法竞赛进阶指南- 月之谜

迭代版本,根据原书的题解编写。

int func(int R)
{
	int res = 0;
	vector<int> arr;
	int r = R;
	int N = 0;//确定R有N位
	while (r){
		N ++ ;
		int mod = r % 10;
		arr.push_back(mod);
		r /= 10;
	}

	vector<vector<vector<vector<int>>>> dp(6,
		vector<vector<vector<int>>>(50,
		vector<vector<int>>(50, vector<int>(50, 0))));

	//边界
	for (int p = 0; p <= 9; p++)
	{
		for (int k = 1; k <= 45; k++)
		{
			int l = p%k;
			dp[1][p][k][l] = 1;
			dp[0][0][k][0] = 1;
		}
	}


	for (int i = 2; i <= N; i++){
		for (int j = 1; j <= 9 * i; j++){
			for (int k = 1; k <= j; k++){
				for (int l = 0; l < k; l++){
					for (int p = 0; p <= 9; p++){
						int mod = (int)(l - p*pow(10, i - 1)) % k;
						while (mod < 0)mod += k;
						if (j >= p)
							dp[i][j][k][l] += dp[i - 1][j - p][k][mod];
						else{
							break;
						}				
					}
				}
			}
		}
	}

	//cout << dp[2][8][8][0];
	//cout << endl;
	
	for (int sum = 1; sum <= 9*N; sum++){
		int t = 0;
		int q = 0;
		for (int i = N; i; i--){
			bool flag = false;
			for (int p = 0; p <= 9; p++){
				if (t+p <= sum){
					if (p < arr[i - 1]){
						int mod = (int)(sum - q - p*pow(10, i - 1)) % sum;
						while (mod < 0)mod += sum;
						res += dp[i-1][sum - t - p][sum][mod];
					}else{
						if (i == 1){
							int mod = (int)(sum - q - p*pow(10, i - 1)) % sum;
							while (mod < 0)mod += sum;
							res += dp[i - 1][sum - t - p][sum][mod];
						}
						t += p;
						q = (int)(q + p*pow(10, i - 1)) % sum;
						break;
					}
				}
				else{
					flag = true;break;
				}}
			if (flag)break;
		}}
	return res;
}

网上也有大神通过记忆化搜索求解。这里提供copy来的代码,shame on me.

long long f[20][170][170];
int a[20];

long long dfs(int pos, int sum, int val, int mod, int lim)
{
	long long ans = 0;
	if (pos == -1) return sum == 0 && val == 0;
	if ((pos + 1) * 9<sum) return 0; // 剪枝而已无须在意
	if (!lim && f[pos][sum][val] != -1) return f[pos][sum][val];
	int up = lim ? a[pos] : 9;
	for (int i = 0; i <= up; i++)
	{
		if (sum<i) break;
		ans += dfs(pos - 1, sum - i, (val * 10 + i) % mod, mod, lim && i == up);
	}
	if (!lim) f[pos][sum][val] = ans;
	return ans;
}

long long solve(long long n)
{
	int cnt = 0;
	long long ans = 0;
	memset(a, 0, sizeof(a));
	while (n)
	{
		a[cnt++] = n % 10;
		n /= 10;
	}
	for (int i = 1; i <= 9 * cnt; i++)
	{
		memset(f, -1, sizeof(f));
		ans += dfs(cnt - 1, i, 0, i, 1);
	}
	return ans;
}

大家可以对比看一下这两种方法的结果。

int main() 
{
	int n = 100;
	int res1 = func(n);
	cout << res1 << endl;

	long long res2 = solve(n);
	cout << res2 << endl;

	system("pause");
}

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-05-10 12:08:32  更:2022-05-10 12:12:45 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年10日历 -2024/10/24 10:22:54-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码