题目
Given nn positive numbers, ZJM can select exactly KK of them that sums to SS. Now ZJM wonders how many ways to get it!
Input
The first line, an integer T<=100 T<=100, indicates the number of test cases. For each case, there are two lines. The first line, three integers indicate nn, KK and SS. The second line, nn integers indicate the positive numbers.
Output
For each case, an integer indicate the answer in a independent line.Example
Input
1
10 3 10
1 2 3 4 5 6 7 8 9 10
Output
4
Note
Remember that k<=n<=16 k<=n<=16 and all numbers can be stored in 32-bit integer
思路
将所有可以组合的数录入到数组a中,然后递归调用求可能组合数的函数,在递归调用中若sum和K恰好同时减到0,则求得一组满足条件的解,否则分别在递归函数中再递归调用 solve(i+1,sum,K)和 solve(i+1,sum-a[i],K-1),最终所得的组合数即为所求所有可能用K个数组合成S的组合个数。
错误问题
1、
第一次运行结果错误,检查发现错误如下:
if(K<0||sum<0) return;
solve(i+1,sum,K);//不选
solve(i+1,sum-a[i],K--);//选
其中K–为做完函数运算后再减,应该为如下:
if(K<0||sum<0) return;
solve(i+1,sum,K);//不选
solve(i+1,sum-a[i],K-1);//选
运行结果正确
代码
#include<iostream>
using namespace std;
int totl=0,n,K,S,a[1000];//a用于存储数据
void solve(int i,int sum,int K)//调用递归函数求所有可能组合的数量
{
// cout<<sum<<' '<<K<<' '<<totl<<endl;
if(K==0&&sum==0)
{
totl++;
return;
}
//判断是否到边界
if(i>=n) return;
//可行性剪枝
if(K<0||sum<0) return;
solve(i+1,sum,K);//不选
solve(i+1,sum-a[i],K-1);//选
}
int main()
{
int T;
cin>>T;
for(int i=0;i<T;i++)
{
cin>>n>>K>>S;
for(int j=0;j<n;j++)
cin>>a[j];
totl=0;
solve(0,S,K) ;
cout<<totl<<endl;
}
return 0;
}