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$。

dfs,剪枝,回溯

#include<iostream>  
#include<algorithm>
using namespace std;

//
//从头开始,参数有当前调料,与当前指数,都是从初始开始往后的
// 此时,满足题意的只会出现在当前调料数过10,即11时,
// 如果此时与输入的相同,则是答案,否则,则不是
// 但无论如何都超过了,最后都要return
// 输出时,可用二维数组,记录当前的答案,最后再输出
//
const int maxkind = 10 + 5,maxans=1e5;
int cnt = 0, a[maxkind],ans[maxans][maxkind], amount;
void dfs(int cur, int index){
	if (cur > 10) {
		if (index == amount) {
			cnt++;
			for (int i = 1; i <= 10; i++) {
				ans[cnt][i] = a[i];
			}
		}
		return;
	}
	for (int i = 1; i <= 3; i++) {//代表给当前调料要加的数量,不++,直接给总的
		if (i + index > amount)break;//要加的和已有的超过了,则往后的肯定也超过,直接退出,剪枝
		a[cur] = i;//直接给总的,并不再提了
		dfs(cur + 1, index + i);//往后找
		a[cur] = 0;//回溯
	}
}
int main()
{
	cin >> amount;
	dfs(1, 0);
	cout << cnt << endl;
	for (int i = 1; i <= cnt; i++) {
		for (int j = 1; j <= 10; j++) {
			cout << ans[i][j] << " ";
		}
		cout << endl;
	}
	
   
}

有点小问题 

#include<iostream>  
#include<algorithm>
using namespace std;

//
//剩余调料数s,当前调料种类k
// 当前调料数满足条件是说还没到三,不满足是说到了3
// 剩余满足是说还大于0
// 需要回溯
// 都满足时,a[k]++,s--
// 当前不满足,剩余满足,k--,s不变
// 都不满足,直接return
// 剩余不满足,当前满足,return
// 即剩余为0时退出
// 
// 要统计有几种情况
// 要输出每种情况
//
const int maxkind = 10 + 5;
int cnt = 0, a[maxkind],amount;
void dfs(int sheng, int kind) {
	if (sheng == 0) {
		cnt++;
		for (int i = 1; i <= 10; i++) {
			cout << a[i] << " ";
		}
		cout << endl;
		return;
	}
	if (kind == 0) {
		return;
	}
	if (a[kind] < 3) {
		a[kind]++, sheng--;
		dfs(sheng, kind);
		a[kind]--, sheng++;
	}
	if (a[kind] == 3) {
		kind--;
		dfs(sheng, kind);
	}
}
void dfss(int sheng, int kind) {
	if (sheng == 0) {
		cnt++;
		return;
		
	}
	if (kind == 0) {
		return;
	}
	if (a[kind] < 3) {
		a[kind]++, sheng--;
		dfss(sheng, kind);
		a[kind]--, sheng++;
	}
	if (a[kind] == 3) {
		kind--;
		dfss(sheng, kind);
	}
}
int main()
{
	cin >> amount;
	if (amount < 10) {
		cout << 0;
	}
	for (int i = 1; i <= 10; i++) {
		a[i] = 1;
	}
	if (amount == 10) {
		cout << 1 << endl;
		for (int i = 1; i <= 10; i++) {
			cout << a[i] << " ";
		}
	}
	else {
		
		for (int i = 10; i >= 1; i--) {
			dfss(amount-10, i);
		}
		cout << cnt << endl;
		for (int i = 10; i >= 1; i--) {
			dfs(amount - 10, i);
		}
	}
   
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值