A - 选数问题

题目

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;
 } 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值