版权声明:本文为阿木寺的原创文章,未经本人允许不得转载。 https://blog.csdn.net/amusi1994/article/details/82793376
题目描述
小米之家是成人糖果店。里面有很多便宜,好用,好玩的产品。中秋节快到了;小米之家想给米粉们准备一些固定金额大礼包。对于给定的一个金额,需要判断能不能用不同种产品(一种产品在礼包最多出现一次)组合出来的这个金额。聪明的你来帮帮米家的小伙伴吧。
输入
输入N(N是正整数,N<=200)
输入N个价格p(正整数,p<10000)用单空格分割
输入金额M(M是正整数,M<=100000)
输出
能组合出来输出 1
否则输出 0
样例输入
6
99 199 1999 10000 39 1499
10238
样例输入
1
题目解析
关键词:
- 背包问题
- k-sum
- 寻找和为定值的多个数
Python代码
# Summary: 小米大礼包
# Author: Amusi
# Date: 2018-09-20
# Reference: https://www.geeksforgeeks.org/subset-sum-problem-dp-25/
# A recursive solution for subset sum
def isSubsetSum(set,n, sum) :
# Base Cases
if (sum == 0) :
return True
if (n == 0 and sum != 0) :
return False
# If last element is greater than
# sum, then ignore it
if (set[n - 1] > sum) :
return isSubsetSum(set, n - 1, sum);
# else, check if sum can be obtained
# by any of the following
# (a) including the last element
# (b) excluding the last element
return isSubsetSum(set, n-1, sum) or isSubsetSum(set, n-1, sum-set[n-1])
N = int(input())
gift_money = list(map(int, input("").split()))
#print(gift_money)
M = int(input())
res=isSubsetSum(gift_money,N, M)
if res:
print(1)
else:
print(0)
C++相关代码
// 21题递归方法
//copyright@ July && yansha
//July、yansha,updated。
#include<list>
#include<iostream>
using namespace std;
list<int>list1;
void find_factor(int sum, int n)
{
// 递归出口
if (n <= 0 || sum <= 0)
return;
// 输出找到的结果
if (sum == n)
{
// 反转list
list1.reverse();
for (list<int>::iterator iter = list1.begin(); iter != list1.end(); iter++)
cout << *iter << " + ";
cout << n << endl;
list1.reverse();
}
list1.push_front(n); //典型的01背包问题
find_factor(sum - n, n - 1); //放n,n-1个数填满sum-n
list1.pop_front();
find_factor(sum, n - 1); //不放n,n-1个数填满sum
}
int main()
{
int sum, n;
cout << "请输入你要等于多少的数值sum:" << endl;
cin >> sum;
cout << "请输入你要从1.....n数列中取值的n:" << endl;
cin >> n;
cout << "所有可能的序列,如下:" << endl;
find_factor(sum, n);
return 0;
}