2022——蓝桥杯十三届2022国赛大学B组真题

问题分析

看到这个问题的同学很容易想到用十层循环暴力计算,反正是道填空题,一直算总能算得出来的,还有些同学可能觉得十层循环太恐怖了,写成回溯更简洁一点。像下面这样

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
int cnt=0;
vector<bool> used(2023,false);
void dfs(int now,int len,int start) {
	if(len==10){
		if(now==2022){
			cnt++;
		}
		return;
	}
	for(int i=start;i<=2022-now;i++){
		if(!used[i]){
			used[i]=true;
			dfs(now+i,len+1,i+1);
			used[i]=false;
		}
	}
}
int main() {
	dfs(0,0,1);
	cout<<cnt<<endl;
	return 0;
}

但是我们分析一下,这个时间复杂度大概是 O ( C 2022 10 ) O(C_{2022}^{10}) O(C202210)级别的,这个数字太恐怖了,要高于 1 0 30 10^{30} 1030的数量级,而c++代码在平台上运行的速度大概是 1 0 9 10^{9} 109次每秒。所以,根本不可能暴力求出答案。而回溯不可以,我们可以动态规划嘛。这实际上就是典型的 限量背包问题(如果不知道什么是限量背包问题,可以看我的这篇博客)。从物品(1~2022)中挑选10个物品,要求每种物品只能选一次,然后装满该背包(容量2022)有多少种组合?将该问题转化为背包问题就很容易解决了。(不过要记得用long long,这个数字很大)

具体代码如下

cpp 复制代码
#include<iostream>
using namespace std;
long long int f[11][2023]= {0}; //f[j][k]:选择了j个物品满载容积k的背包的组合数 
int i, j, k;
int main() {
	f[0][0]=1;
	for(i=1; i<=2022; i++) {//遍历每个物品 
		for(k=2022; k>=i; k--) {//遍历背包容量,从后往前遍历 
			for(j=1; j<=10; j++) {//遍历每个选择数量 
				f[j][k]+=f[j-1][k-i];
			}
		}
	}
	cout << f[10][2022];
	return 0;
}

结果

相关推荐
大阳1232 分钟前
线程(基本概念和相关命令)
开发语言·数据结构·经验分享·算法·线程·学习经验
weixin_307779131 小时前
VS Code配置MinGW64编译GNU 科学库 (GSL)
开发语言·c++·vscode·算法
学行库小秘2 小时前
ANN神经网络回归预测模型
人工智能·python·深度学习·神经网络·算法·机器学习·回归
没落之殇2 小时前
基于C语言实现的HRV分析方法 —— 与Kubios和MATLAB对比
算法
秋难降2 小时前
线段树的深度解析(最长递增子序列类解题步骤)
数据结构·python·算法
楚韵天工2 小时前
基于GIS的无人机模拟飞行控制系统设计与实现
深度学习·算法·深度优先·无人机·广度优先·迭代加深·图搜索算法
你也向往长安城吗3 小时前
推荐一个三维导航库:three-pathfinding-3d
javascript·算法
蒋星熠4 小时前
C++零拷贝网络编程实战:从理论到生产环境的性能优化之路
网络·c++·人工智能·深度学习·性能优化·系统架构
百度智能云4 小时前
VectorDB+FastGPT一站式构建:智能知识库与企业级对话系统实战
算法
CHANG_THE_WORLD4 小时前
# C++ 中的 `string_view` 和 `span`:现代安全视图指南
开发语言·c++