栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

7-1 找零钱*** (20 分)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

7-1 找零钱*** (20 分)

收银员现有 n 张面值分别为 v

的纸币。若找零金额为 m,则一共有多少种找零方法?

注:0 输入格式

输出格式
若有解,则输出全部找零方案,每输出一种 若无解,则输出“None”

输入样例1

6
3 1 4 3 2 7
9

结尾无空行
输出样例1

3 1 3 2
3 4 2
4 3 2
2 7

输入样例2

5
5 3 4 6 7
2

结尾无空行
输出样例2

None

知识点:回溯,剪枝。

思路:本题为子集问题,(即可以分为选与不选两种情况,不需要用个for循环,直接在dfs中写出两种情况,在此基础上进行剪枝)dfs(i,sum,op)(i为第i个元素,sum为选中的元素和,op是数组用来标记第i个元素选不选)

纠正:刚开始在dfs中用for循环进行遍历访问,其实不用,因为该题为子集问题不需要,for一般用于全排列

代码:

#include
using namespace std;
int n;
int rm = 0;
int op[1005];
int v[1005];
int m;
int flag = 0;
void dfs(int i,int sum,int cnt) {
	if (i>n) {
		if (sum == m) {
			flag = 1;
			int j = cnt;
			for (int k = 1;k <= n;k++) {
				if (j == 1 && op[k] == 1) {
					cout << v[k] << endl;
				}
				else if (op[k] == 1) {
					cout << v[k] << " ";
					j--;
				}
			}
		}
		return;
	}
	op[i] = 1;
	if(sum + v[i]<=m)
		dfs(i + 1, sum+v[i],cnt+1);
	op[i] = 0;
	dfs(i + 1, sum,cnt);
}
int main() {
	cin >> n;
	for (int i = 1;i <= n;i++) {
		cin >> v[i];
		rm += v[i];
	}
	cin >> m;
	dfs(1,0,0);
	if (flag == 0)
		cout << "None" << endl;
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/511794.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号