😊😊 😊😊
不求点赞,只求耐心看完,指出您的疑惑和写的不好的地方,谢谢您。本人会及时更正感谢。希望看完后能帮助您理解算法的本质
😊😊 😊😊
题目描述:
原题链接
小白到进阶各种解法:
一、暴搜:😊
思路:
- 题意分析:给定一个n,然后10个位置,每个位置有三种取值,且每个位置必须存在值,请问你有多少种不同的方案,并且输出方案:其中 [1 1 2] [1 2 1]是不同的两种方案。
- 10个位置,则需要枚举每个位置。则位置可以作为阶段 ⇒ 推动阶段向下走。然后每个位置上三个数,需要枚举每个位置上放哪个数的所有情况 ⇒ 每个阶段怎么处理!
- 若采用暴力循环的话,则需要写10个 f o r for for 循环。所以我们这里采用递归,递归每个位置,枚举每个位置上放哪个数。
- 回溯的时候更新方案,然后递归下一种情况。
- 递归的出口:当10个阶段都已经处理完毕了,则可以进行判断了。剪枝优化:如果中途发现答案大于 n n n,则可以剪枝!
- 递归的参数:(u, sum):分别表示第 u u u 个位置,当前位置上的元素总和为 s u m sum sum。
- 递归的计算:每个位置上可以放置三个数!循环枚举三个数,每次将当前位置上放置某个数后,那么往下递归,枚举当前位置所产生的情况!
- 由于本题要输出方案总数,且方案总数是先于方案输出。所以我们不能像下面这样写。需要记录方案。😔生活不易闭自闭。
void dfs(int u, int sum)
{
if (sum > n) {
return ;
}
if (u > 10) {
if (sum == n){
for (int i=1; i <= 10; i ++)
cout << path[i] << ' ';
puts("");
}
return ;
}
for (int i=1; i <= 3; i ++)
{
path[u] = i;
dfs(u+1, sum + i);
}
}
- 如何记录方案呢?我们可以采用二维矩阵的方案,或者采用vector存储。
代码:
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int n;
int path[20];
int ways[10100][11]; //每一行就是一个方案!
int cnt; //记录方案数!
void dfs(int u, int sum)
{
if (sum > n) {
return ;
}
if (u > 10) {
if (sum == n){
cnt ++;
for (int i=1; i <= 10; i ++)
ways[cnt][i] = path[i];
}
return ;
}
for (int i=1; i <= 3; i ++)
{
path[u] = i;
dfs(u+1, sum + i);
}
}
int main()
{
cin >> n;
dfs(1, 0);
cout << cnt << endl;
for (int i=1; i <= cnt; i ++)
{
for (int j=1; j <= 10; j ++)
cout << ways[i][j] << ' ';
cout << endl;
}
return 0;
}
二、记忆化搜索:待更新😊
代码:
三、本题考察算法:😊
代码: