A - 选数问题(递归实现dfs)

选数问题

  • 题意: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<=100T<=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.
    在这里插入图片描述

  • 解题思路
    选数时需要进行dfs,本题利用递归实现。定义三个变量分别记录当前数的位置,当前所选数的个数以及已选数的和,从(1,0,0)开始递归,每次先进行判断,如果所选数和已选数的和都等于要求时结束函数,计数器加一,计数器记录满足条件的情况。

    同时需要及时进行剪枝优化程序,即当所选数数目超过要求或已选数的和已经大于要求的和,及时结束本次函数调用,返回上一层,继续向下递归。当第一层dfs调用完毕,计数器存储值即为方案数。

  • 拓展延伸
    如果要输出方案,可以新开一个数组记录每个方案中所选的数,利用vector较为方便,要选的数加入在数组尾端不选的删除(push_back和pop_back),递归完成后输出方案即可。

  • 代码实现

#include <iostream> 
#include <cstring>
using namespace std;

int n,num,limit,ans,p;
int a[2000];

void dfs(int x,int y,int z)//x:数组中第x个数,y:已选数的个数,z:已选数的和 
{
	if(y == limit && z == ans) 
	{
		p++;	
		return;		
	}
	
	if(y > limit || z > ans)
		return;
		
	for(int i=x ;i<=num; i++)
	{
		//cout<<a[i]<<endl;
		dfs(i+1,y+1,z+a[i]);
	}
		
}

int main()
{
	cin>>n;
	while(n--)
	{
	    cin>>num>>limit>>ans;
		memset(a,0,sizeof(a) );
		for(int i=1;i<=num;i++)
			cin>>a[i];
		p=0;
		dfs(1,0,0);
		cout<<p<<endl;
	}
}


发布了19 篇原创文章 · 获赞 0 · 访问量 656

猜你喜欢

转载自blog.csdn.net/Hdjjdsbjj/article/details/104729689