P2089 烤鸡(DFS)

题目背景

猪猪 Hanke 得到了一只鸡。

题目描述

猪猪 Hanke 特别喜欢吃烤鸡(本是同畜牲,相煎何太急!)Hanke 吃鸡很特别,为什么特别呢?因为他有 10 种配料(芥末、孜然等),每种配料可以放 1 到 3 克,任意烤鸡的美味程度为所有配料质量之和。

现在, Hanke 想要知道,如果给你一个美味程度 n ,请输出这 10 种配料的所有搭配方案。

输入格式

一个正整数 n,表示美味程度。

输出格式

第一行,方案总数。

第二行至结束,10 个数,表示每种配料所放的质量,按字典序排列。

如果没有符合要求的方法,就只要在第一行输出一个 0。

输入输出样例

输入 #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≤5000。

题目链接:P2089 烤鸡 - 洛谷

学习链接:递推与递归 + DFS | 手把手带你画出递归搜索树_哔哩哔哩_bilibili

解题思路: 

  1. 用1、2、3三个数字进行组合,每个组合10个元素
  2. 求出组合元素和sum,输出sum==n的组合,并累计方案,且按字典序排序
  3. 剪枝:sum>n,终止搜索
  4. sum在1*10~3*10之间,所以 n<10 || n>30,没有符合要求的方法,直接输出0 

代码如下: 

#include<bits/stdc++.h>
using namespace std;
int n;//美味程度
int t[59050];//记录符合条件的组合 
int result[59050][15];//记录所有组合方案,最多3^10=59049
int cnt=0;//累计方案数 

void dfs(int x,int sum)
{
	//如果sum>n,没有枚举下去的必要了,直接剪枝
	if(sum>n)	return ;
	
	//如果枚举超过了10个元素,即找到了一个组合
	if(x>10) 
	{
		//如果组合元素和sum==n,即找到了一个符合要求的方案
		if(sum==n)
		{
			cnt++;
			for(int i=1;i<=10;i++)
			{
				result[cnt][i]=t[i];//result[cnt][]表示第cnt个组合 
			}
		} 
		return ;//不管找没找到sum==n的方案,都要结束搜索 
	}
	for(int i=1;i<=3;i++)
	{
		//将数字装入桶t[] 
		t[x]=i;
		//开始枚举下一个位置,sum+=i
		dfs(x+1,sum+i);
		
		//撤出元素,腾出位置,便于下一元素装入桶,进行新的组合
		t[x]=0; 
		 
	}
} 
int main()
{
	cin>>n;
	
	//美味程度的可能范围:10~30 
	if(n<10 || n>30)
	{
		cout<<0<<endl;
		return 0;	
	}
		
	dfs(1,0);//从第一个位置开始枚举,sum==0 
	
	if(cnt>0)
	{
		cout<<cnt<<endl;
		for(int i=1;i<=cnt;i++)//枚举第i个方案 
		{
			for(int j=1;j<=10;j++)//枚举组合排列 
			{
				cout<<result[i][j]<<" ";
			}
			cout<<endl;
		}
	}
	else
		cout<<0<<endl; 
	return 0;
}

 希望能帮助到各位同志,祝天天开心,学业进步!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值