洛谷P2089 烤鸡 题解 递归

news/2024/12/14 4:00:15/文章来源:https://www.cnblogs.com/quanjun/p/18606225

题目链接:https://www.luogu.com.cn/problem/P2089

题目大意:

\(10\) 种配料,每种配料可以放 \(1 \sim 3\) 克。现在要凑成共 \(n\) 克的配料。问:

  1. 有多少种不同的方案?
  2. 按字典序从小到大输出所有方案。

解题思路:

我们可以设计一个递归函数 void put(int d)。其中 \(d\) 表示我目前正在考虑放多少克第 \(d\) 种配料,此时我有三种选择:

  1. \(1\) 克第 \(d\) 种配料,然后接着去放第 \(d+1\) 种配料;
  2. \(2\) 克第 \(d\) 种配料,然后接着去放第 \(d+1\) 种配料;
  3. \(3\) 克第 \(d\) 种配料,然后接着去放第 \(d+1\) 种配料。

这个很容易用算法实现,如果我们开一个数组 \(a\),并用 \(a[d]\) 记录第 \(d\) 种配料放了多少克的话,则此时我们只需要:

  1. put(d) 函数中从 \(1\)\(3\) 枚举 \(i\)(它表示第 \(d\) 种配料放了 \(i\) 克)
  2. 然后去放第 \(d+1\) 种配料即可。

代码的整体逻辑如下:

void put(int d) {for (int i = 1; i <= 3; i++) {a[d] = i; // 第d种配料放了i克dfs(d+1);}
}

但是此时我们只是设计了递归的逻辑,并没有考虑何时递归会结束(因为递归肯定是需要结束的),所以接着我们来思考递归何时结束。

当我们调用 put(d) 时,此时我们正在考虑第 \(d\) 种配料放多少克,同时,也说明我们已经放好了第 \(1, 2, \ldots, d-1\) 种配料(所以现在才会在考虑第 \(d\) 种配料)。

所以递归的边界条件可以定为 \(d \gt 10\)(即 \(d = 11\))时,此时前 \(d-1\)(即前 \(10\) 种调料)都已经放好了,我们只需要统计以下 \(\sum\limits_{i=1}^{10} a[i]\) 是否等于 \(n\) 即能够确定它是否是一种合法的方案了。

但是本题中我们有两个问题要求解:

  1. 计算总共有多少种不同的方案;
  2. 按照字典序从小到大输出每一种方案。

这两个逻辑对应的递归边界条件不一样。

1. 计算总共有多少种不同的方案

如果是计算有多少中不同的方案数,则可以开一个全局变量 ans,每次碰到一个满足条件的方案,执行 ans++

void put(int d) {if (d == 11) { // 边界条件:10种配料都选好了int sum = 0; // 开个累加器统计10种配料的重量和for (int i = 1; i <= 10; i++)sum += a[i];if (sum == n) { // 合法的方案ans++;}return; // 递归边界,处理好后要返回,不需要继续递归了}for (int i = 1; i <= 3; i++) {a[d] = i; // 第d种配料放了i克dfs(d+1);}
}

2. 按照字典序从小到大输出每一种方案

如果要输出所有方案,则我们只需要将上述代码中 ans++; 这条语句修改为输出 \(a[1], a[2], \ldots, a[10]\) 的逻辑即可。

void put(int d) {if (d == 11) { // 10中配料都选好了...if (sum == n) { // 合法的方案for (int i = 1; i <= 10; i++)cout << a[i] << " ";cout << endl;  // 输出该合法方案}return; // 递归边界,处理好后要返回,不需要继续递归了}for (int i = 1; i <= 3; i++) { ...

(注:省略的部分都一样)

所以我们会发现,两种情况下递归函数 put(d) 除了边界条件的处理不一样,其它处理都是一模一样的。

如何解决这个问题呢?

一种方法是写两个递归函数,但是那样代码会显得很冗杂。

另一种方法是给 put 函数增加一个参数,即 void put(int d, bool flag)

  • flag 为 true 时,使 ans++;
  • flag 为 false 时,输出这个方案。

修改后的 put(d, flag) 函数如下:

void put(int d, bool flag) {if (d == 11) { // 10中配料都选好了int sum = 0; // 开个累加器统计10种配料的重量和for (int i = 1; i <= 10; i++)sum += a[i];if (sum == n) { // 合法的方案if (flag)   // 方案数 +1ans++;else {      // 输出这种方案for (int i = 1; i <= 10; i++)cout << a[i] << " ";cout << endl;}}return; // 递归边界,处理好后要返回,不需要继续递归了}for (int i = 1; i <= 3; i++) {a[d] = i; // 第d种配料放了i克put(d+1, flag);}
}

接着我们只需要:

  1. 调用 puts(1, true),函数调用结束时输出 ans 即为总的方案数;
  2. 调用 puts(1, false) —— 它能够输出所有方案。

完整的代码如下:

#include <bits/stdc++.h>
using namespace std;
int a[11], n, ans;void put(int d, bool flag) {if (d == 11) { // 10中配料都选好了int sum = 0; // 开个累加器统计10种配料的重量和for (int i = 1; i <= 10; i++)sum += a[i];if (sum == n) { // 合法的方案if (flag)   // 方案数 +1ans++;else {      // 输出这种方案for (int i = 1; i <= 10; i++)cout << a[i] << " ";cout << endl;}}return; // 递归边界,处理好后要返回,不需要继续递归了}for (int i = 1; i <= 3; i++) {a[d] = i; // 第d种配料放了i克put(d+1, flag);}
}int main() {cin >> n;put(1, true);cout << ans << endl;put(1, false);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/852330.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

应用题3

这道题知识点参考书116页二叉树遍历相关知识。 知识点:二叉树中序遍历,后序遍历的顺序是什么如何将一棵二叉树转化为树(或森林)中序遍历(左->根->右)后序遍历(左->右->根)根据中序遍历和后序遍历的特点,我们可以知道,中序遍历中根节点在中间,后序遍历中…

河北知识付费系统热门课程是什么

在当今科技快速发展的社会环境中,教育领域也随之发生着深刻的变革。尤其是随着互联网及数字媒体的应用日渐普及,知识付费及在线教育成为了新时代学习者的优选途径。河北的知识付费系统通过其丰富的教学资源与创新的教学模式满足了不同年龄、层次的学习者多样化的需求。为了回…

转载:【AI系统】AI 框架作用

深度学习范式主要是通过发现经验数据中,错综复杂的结构进行学习。通过构建包含多个处理层的计算模型(网络模型),深度学习可以创建多个级别的抽象层来表示数据。例如,卷积神经网络 CNN 可以使用大量图像进行训练,例如对猫狗分类去学习猫和狗图片的特征。这种类型的神经网络…

转载:【AI系统】卷积操作原理

卷积是神经网络里面的核心计算之一,它是一种特殊的线性运算。而卷积神经网络(CNN)是针对图像领域任务提出的神经网络,其受猫的视觉系统启发,堆叠使用卷积层和池化层提取特征。它在 CV 领域方面的突破性进展引领了深度学习的热潮。 回到卷积本身,其变种丰富、计算复杂,神…

转载:【AI系统】Winograd 算法

在上一篇文章的介绍中,介绍了 Im2Col 技术,它通过将三维张量重新排列成矩阵形式,然后利用基于内存访问局部性的优化库如 GEMM(通用矩阵乘法库)加速计算。随后,还探讨了空间组合优化,这一种利用局部性原理来提升效率的技术。 在本文将重点介绍 Winograd 优化算法,它是矩…

转载:【AI系统】Im2Col 算法

作为早期的 AI 框架,Caffe 中卷积的实现采用的是基于 Im2Col 的方法,至今仍是卷积重要的优化方法之一。 从上一篇文章的介绍中可以看到,在 CNN 中卷积直接计算的定义中,卷积核在输入图片上滑动,对应位置的元素相乘后相加求和,滑窗的大小由卷积核决定。由于滑动操作时的窗…

转载:【AI系统】模型转换基本介绍

模型转换的主要任务是实现模型在不同框架之间的流转。随着深度学习技术的发展,训练框架和推理框架的功能逐渐分化。训练框架通常侧重于易用性和研究人员的算法设计,提供了分布式训练、自动求导、混合精度等功能,旨在让研究人员能够更快地生成高性能模型。 而推理框架则更专注…

转载:【AI系统】知识蒸馏原理

本文将介绍知识蒸馏(Knowledge Distillation, KD)的原理,这是一种通过从大型的教师模型向小型的学生模型转移知识来实现模型压缩和优化的技术。知识蒸馏的核心思想是利用教师模型在大量数据上积累的丰富知识,通过特定的蒸馏算法,使学生模型能够学习并吸收这些知识,从而达…

DDCA —— 内存一致性

CS6810 Chapter 5. Multi-threading, Synchronization, Consistency. 的学习笔记,详细介绍了同步、构造锁、缓存锁、Test-and-Test-and-Set、负载链接和条件存储,以及内存一致性模型和事务内存。1. 同步(Synchronization) 1.1 构造锁(Locks)原子(atomic)执行:应用程序…

Consul 学习总结

什么是Consul? Consul是一种服务网络解决方案,使团队能够管理服务之间以及跨本地和多云环境和运行时的安全网络连接。Consul提供服务发现、服务网格(service mesh)、流量管理和网络基础设施设备的自动更新。可以在单个Consul部署中单独或一起使用这些功能。 架构介绍 Consul提…

转载:【AI系统】GhostNet 系列

本文主要会介绍 GhostNet 系列网络,在本文中会给大家带来卷积结构的改进方面的轻量化,以及与注意力(self-attention)模块的进行结合,部署更高效,更适合移动计算的 GhostNetV2。让读者更清楚的区别 V2 与 V1 之间的区别。 GhostNet V1 模型 GhostNet V1:提供了一个全新的 Gh…

转载:【AI系统】ShuffleNet 系列

本文会介绍 ShuffleNet 系列,重点在于其模型结构的轻量化设计,涉及如何降低深度网络计算量,在本文中会着重会讲解逐点分组卷积(Pointwise Group Convolution)和通道混洗(Channel Shuffle)两种新的运算,而 V2 版本则会从设备运算速度方面考虑将网络进行轻量化。 ShuffleNet …