递归——合理消费

描述
计算概论期终考试结束后,同学B感觉自己得到了解脱。回想起复习期间的艰苦岁月,B决定去某新开的食堂大吃一顿。

B同学希望今天把饭卡的钱全部花完,以抚慰自己受伤的心灵。

已知B的饭卡里有钱p元,给定食堂物品的价格列表(价格不重复),请你给出所有可能的恰好把p元花掉的购买选择。

如:p=7, 食堂现有价格为 [3,2,6,7]  的物品,则可能的购买选择有:

[3, 2, 2]

[7]

每种价格的物品可以多次选购。
关于输入
n+1行
第1行有两个整数,分别为物品种类n, 以及B卡里多少钱p。
接下来有n行,每行一个数,为每种物品的价格xi。
满足:3<= n <= 10;2<= p <= 200;2<= xi <=100。
关于输出
所有可能的购买选择,每种选择一行,要求不重复。
对于每一种选择,价格的顺序要求按照输入顺序。
每种物品可以多次选购无限制。

如果没有恰好花掉的选择,则输出"NO"。
例子输入
4 7

3

2

6

7
例子输出
3 2 2

7

思路:

本题递归时有两种情况:

①选择第k件物品,下次仍从第k件物品开始(因为物品可重复)

②不选择第k件物品,下次从第k+1件物品开始

#include<iostream>
using namespace std;
int n;
int p;
int cost[11] = {};
int num = 0;
int choose[30] = {};
int x = 0;
void f(int k, int y)//第k个物品,目前的消费y元
{
	if (y == p) {//如果恰好花完p元
		++num;
		for (int i = 0; i < x; ++i) {//输出所储存的方案
			cout << choose[i];
			if (i < x - 1) {
				cout << " ";
			}
		}
		cout << endl;
		return;
	}
	if (k == n || y > p) {//如果没有恰好花完p元,返回
		return;
	}
	choose[x++] = cost[k];//如果选择了第k件物品
	f(k, y + cost[k]);//继续消费
	x--;//回溯
	choose[x] = 0;//回溯
	f(k + 1, y);//如果不选择第k件物品
}
int main()
{
	cin >> n >> p;
	for (int i = 0; i < n; ++i) {
		cin >> cost[i];
	}
	f(0, 0);
	if (!num) {
		cout << "NO";
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值