P2089 烤鸡 【洛谷】

😊😊 😊😊
不求点赞,只求耐心看完,指出您的疑惑和写的不好的地方,谢谢您。本人会及时更正感谢。希望看完后能帮助您理解算法的本质
😊😊 😊😊

题目描述:

原题链接

小白到进阶各种解法:

一、暴搜:😊

在这里插入图片描述

思路:

  1. 题意分析:给定一个n,然后10个位置,每个位置有三种取值,且每个位置必须存在值,请问你有多少种不同的方案,并且输出方案:其中 [1 1 2] [1 2 1]是不同的两种方案。
  2. 10个位置,则需要枚举每个位置。则位置可以作为阶段 ⇒ 推动阶段向下走。然后每个位置上三个数,需要枚举每个位置上放哪个数的所有情况 ⇒ 每个阶段怎么处理
  3. 若采用暴力循环的话,则需要写10个 f o r for for 循环。所以我们这里采用递归,递归每个位置,枚举每个位置上放哪个数。
  4. 回溯的时候更新方案,然后递归下一种情况。
  5. 递归的出口:当10个阶段都已经处理完毕了,则可以进行判断了。剪枝优化:如果中途发现答案大于 n n n,则可以剪枝!
  6. 递归的参数:(u, sum):分别表示第 u u u 个位置,当前位置上的元素总和为 s u m sum sum
  7. 递归的计算:每个位置上可以放置三个数!循环枚举三个数,每次将当前位置上放置某个数后,那么往下递归,枚举当前位置所产生的情况!
  8. 由于本题要输出方案总数,且方案总数是先于方案输出。所以我们不能像下面这样写。需要记录方案。😔生活不易闭自闭。
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);
	}
}
  1. 如何记录方案呢?我们可以采用二维矩阵的方案,或者采用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;
}

在这里插入图片描述

二、记忆化搜索:待更新😊

在这里插入图片描述

代码:


在这里插入图片描述

三、本题考察算法:😊

代码:



在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值