曾彪彪的个人网站
首页
文章列表
>>
文章详情
烤鸡调料问题(暴搜vs深搜)
作者:
曾彪彪
日期:
2025-08-25 06:30:30
阅读(20)
分类:
问题记录
Algorithm
# P2089 烤鸡 ## 题目背景 猪猪 Hanke 得到了一只鸡。 ## 题目描述 猪猪 Hanke 特别喜欢吃烤鸡(本是同畜牲,相煎何太急!)Hanke 吃鸡很特别,为什么特别呢?因为他有 $10$ 种配料(芥末、孜然等),每种配料可以放 $1$ 到 $3$ 克,任意烤鸡的美味程度为所有配料质量之和。 现在, Hanke 想要知道,如果给你一个美味程度 $n$ ,请输出这 $10$ 种配料的所有搭配方案。 ## 输入格式 一个正整数 $n$,表示美味程度。 ## 输出格式 第一行,方案总数。 第二行至结束,$10$ 个数,表示每种配料所放的质量,按字典序排列。 如果没有符合要求的方法,就只要在第一行输出一个 $0$。 ## 输入输出样例 #1 ### 输入 #1 ``` 11 ``` ### 输出 #1 ``` 10 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 ``` ## 说明/提示 对于 $100\%$ 的数据,$n \leq 5000$。 这道题思路很直接,直接暴力就行。代码如下: ```c++ /** start time: 8:45 End time: Type: simulator Solution: - - - test case: - - - - first submit score: 100 cause: **/ #include <bits/stdc++.h> using namespace std; int main() { int n; cin >> n; long long count = 0; vector<string> list; if (n < 10 || n > 30) { cout << 0; return 0; } // freopen("C:/Users/zengsam/Downloads/P1042_2.in", "r", stdin); for (int a = 1; a <= 3; a++) { for (int b = 1; b <= 3; b++) { for (int c = 1; c <= 3; c++) { for (int d = 1; d <= 3; d++) { for (int e = 1; e <= 3; e++) { for (int f = 1; f <= 3; f++) { for (int g = 1; g <= 3; g++) { for (int h = 1; h <= 3; h++) { for (int i = 1; i <= 3; i++) { for (int j = 1; j <= 3; j++) { int v = a + b + c + d + e + f + g + h + i + j; if (v == n) { string s = ""; s.push_back(a + '0'); s.push_back(b + '0'); s.push_back(c + '0'); s.push_back(d + '0'); s.push_back(e + '0'); s.push_back(f + '0'); s.push_back(g + '0'); s.push_back(h + '0'); s.push_back(i + '0'); s.push_back(j + '0'); list.push_back(s); } if (v > n) { break; } } } } } } } } } } } cout << list.size() << endl; for (string e : list) { for (char c : e) { cout << c << " "; } cout << endl; } return 0; } ``` 这种算法虽然简单直接,不过看了其他大佬的解法,很受启发,原来支持深搜。 为什么可以使用深搜,这里可以把调料成分看作一颗三叉树,每个子节点的值分别是1,2,3.表示配料重量。这棵树有10层。于是有以下dfs解法。 ```c++ /** start time: 8:45 End time: Type: simulator Solution: - - - test case: - - - - first submit score: 100 cause: **/ #include <bits/stdc++.h> using namespace std; vector<vector<int>> ans; int n; vector<int> cur(10); void dfs(int pos, int sum) { int rem = 10 - pos; if (sum + rem * 1 > n) { return; } if (sum + rem * 3 < n) { return; } if (pos >= 10) { if (sum == n) { ans.push_back(cur); } return; } for (int i = 1; i <= 3; i++) { cur[pos] = i; dfs(pos + 1, sum + i); } } int main() { cin >> n; if (n < 10 || n > 30) { cout << 0; return 0; } dfs(0, 0); cout << ans.size() << endl; for (auto &a : ans) { for (auto &e : a) { cout << e << " "; } cout << endl; } return 0; } ``` 这是本渣渣第一次使用深搜解决具体问题,还了解了剪枝的概念。所谓剪枝,就是如果知道结果已经不可能了,就提前退出,不再继续搜索。
评论(0)
评论(必填)
名称(必填)
联系方式(可选)
验证码(必填)
提交
评论(必填)
名称(必填)
联系方式(可选)
验证码(必填)