当前位置: 首页 > news >正文

【洛谷枚举算法】P2089烤鸡

由于每种配料的用量范围是 1 到 3 克,且有 10 种配料,我们可以使用深度优先搜索(DFS)枚举所有可能的配料组合,然后筛选出美味程度等于给定值 n 的组合。

【题目】:
在这里插入图片描述

【算法思路】

  • 全局变量

MAX:常量,代表配料的种类数量,本题中固定为 10。

n:用于存储输入的给定美味程度,该值决定了满足条件的配料组合。

ans:定义为二维向量 std::vector<std::vector<int>>,其作用是存储所有符合要求(即配料总质量等于给定美味程度 n)的配料组合。

path:是一个一维数组,数组长度为 MAX,用来记录在深度优先搜索过程中当前正在探索的配料组合情况。

  • 深度优先搜索函数

函数参数

  • step:表示当前正在考虑的配料编号,取值范围是从 0 到 MAX - 1
  • sum:记录到当前步骤为止,所使用配料的总质量。

搜索范围:基于配料的种类数,本题中 MAX 被设定为 10,意味着需要对 10 种配料进行组合尝试。

存储结构:使用二维向量 ans 来存储所有满足条件的配料组合,无需额外定义二维数组。

标记情况:此问题无需使用标记数组。原因在于 “烤鸡” 问题是对配料组合进行枚举,每种配料的使用情况相互独立,且每个配料都必须被考虑一次,不会出现重复访问同一状态而陷入无限循环的情况。

递归逻辑

  • 未考虑完 10 种配料时:对于当前的配料(编号为 step),其用量有 1 克、2 克、3 克这三种选择。依次枚举这三种用量,将当前配料的用量记录到 path[step] 中,然后递归调用深度优先搜索函数 dfs(step + 1, sum + 当前用量),继续处理下一种配料。
  • 考虑完 10 种配料时:检查当前配料组合的总质量sum是否等于给定的美味程度n
    • 若相等,说明找到了一种满足条件的配料组合。将 path 数组中的内容复制到一个临时向量 temp 中,再把 temp 添加到 ans 向量里。
    • 若不相等,表明该配料组合不符合要求,直接返回,结束当前搜索路径,回溯到上一层继续尝试其他组合。
  • 输出:①从第0种配料开始搜索,最后输出满足条件的配料组合的数量;

②使用范围for循环函数输出每种配料组合

【代码示例】

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

const int MAX = 10;//范围:配料的种类数 
int n;//给定的美味程度 
vector<vector<int>> ans;//存储所有满足条件的配料组合
int path[MAX];//记录当前正在搜索的配料组合

// 深度优先搜索函数
void dfs(int step,int sum){
	//当已经考虑完10种配料
	if(step == MAX){ 
		if(sum == n){//检查总质量是否等于给定的美味程度
			vector<int> temp;
			//将当前的配料组合添加到临时向量中
			for(int i=0;i<MAX;i++){
				temp.push_back(path[i]);
			} 
			//将临时变量添加到结果数组中
			ans.push_back(temp); 
		}
		return;
	} 
	//枚举当前配料的用量
	for(int i=1;i<=3;i++){
		path[step] = i;//设置当前配料的用量
		dfs(step + 1,sum + i);//递归调用处理下一种配料 
	} 
} 

int main(){
	cin>>n;//读取输入的美味程度 
	dfs(0,0);//从第0种配料开始,总质量初始为0
	cout<<ans.size()<<endl;//输出满足条件的配料组合的数量
	
	//输出每种配料组合
	for(const auto& vec : ans){
		for(int i=0;i<MAX;i++){
			cout<<vec[i];
			if(i < MAX-1){
				cout<<" ";
			}
		}
		cout<<endl;
	}
	
	return 0;
}

剪枝优化相关边界条件

假设当前已经考虑了 step 种配料,总质量为 sum,即使后面剩下的 MAX - step种配料都取最小用量 1 克,总质量sum + (MAX - step) 仍然大于 n,或者即使都取最大用量 3 克,总质量sum + 3 * (MAX - step) 仍然小于 n,那么就可以提前终止当前搜索路径。
【代码示例】

if (sum + (MAX - step) > n || sum + 3 * (MAX - step) < n) {
    return;
}

通过剪枝操作,可以减少不必要的递归调用,提高算法的效率。

相关文章:

  • 文件基础IO
  • 笔记五:C语言编译链接
  • [操作系统] ELF文件从形成到加载轮廓
  • 经典核密度估计(Kernel Density Estimation):从直觉到数学
  • DeepSeek:人工智能领域的颠覆者与开拓者
  • deepseek使用记录18——艺术的追问
  • 鸿蒙开发:相对布局RelativeContainer
  • 《实战AI智能体》深度解析Deepseek可以做什么?
  • 概率、泛化与过拟合
  • Python Url地址截取方法
  • 1.4 单元测试与热部署
  • Python——计算机网络
  • vs编译各种报错:未知重写说明符
  • MyBatis 与 JDBC 的关系?
  • 【记录一下】Hierarchical Navigable Small Worlds(HNSW)是什么玩意?
  • VS2022远程调试树莓派上的.net core程序
  • C语言经典案例-菜鸟经典案例
  • C++编写Redis客户端
  • BOOK推荐-学海无涯
  • 大模型工程师学习日记(十五):Hugging Face 模型微调训练(基于 BERT 的中文评价情感分析)
  • 床上爱做网站/外贸seo推广
  • wordpress 特效/百度seo排名软件
  • 大庆做网站的公司/百度账号安全中心官网
  • 镇江个人网站建设/免费发布推广信息的平台有哪些
  • 张家界建设信息网站/网站google搜索优化
  • wordpress留言板页面/长春关键词优化报价