题目背景
猪猪 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、2、3三个数字进行组合,每个组合10个元素
- 求出组合元素和sum,输出sum==n的组合,并累计方案,且按字典序排序
- 剪枝:sum>n,终止搜索
- 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;
}
希望能帮助到各位同志,祝天天开心,学业进步!
8367

被折叠的 条评论
为什么被折叠?



