#150-【DFS】对抗赛

版权声明:反正也没有人会转,下一个 https://blog.csdn.net/drtlstf/article/details/83474522

Description

fiile name: compete

序设计对抗赛设有 N(0 编程要求:对给定 N 及 N 个奖品的价值,求出将这 N 个奖品分成价值相等的两组,共有多少种分法?
例如:N = 5,S1,S2,S3……Sn 分别为 1,3,5,8,9 
则可分为{1,3,9}与{5,8} 
仅有 1 种分法; 
例如:N = 7,S1,S2,S3……Sn 分别为 1,2,3,4,5,6,7 
则可分为: 
{1,6,7}与{2,3,4,5} 
{2,5,7}与{1,3,4,6} 
{3,4,7}与{1,2,5,6} 
{1,2,4,7}与{3,5,6} 
有 4 种分法。

Input

第一行:一个整数N.

第二行:N个数: S1,S2,S3……Sn。(每两个相邻的数据之间有一个空格隔开)。

Output

含一个整数,表示多少种分法的答案,数据若无解,则输出 0。

Sample Input

7 
1 2 3 4 5 6 7

Sample Output

4

记忆化搜索

#include <iostream>
#include <cstdio>
#include <cstring>

#define SIZE 110
#define NUM 5010

using namespace std;

int f[NUM][SIZE], a[SIZE], n, res;

int dfs(int less, int limit) // less还剩下多少空间,limit要从那个地方开始找
{
	int i, res = 0;
	
	if (!less)
	{
		return 1;
	}
	if (~f[less][limit]) // 如果已经被查找过
	{
		return f[less][limit];
	}
	for (i = limit + 1; i <= n; ++i)
	{
		if (less >= a[i])
		{
			res += dfs(less - a[i], i);
		}
	}
	
	return f[less][limit] = res;
}

int main(void)
{
	int i, tot = 0;
	
	scanf("%d", &n);
	for (i = 1; i <= n; ++i)
	{                     
		scanf("%d", &a[i]);
		tot += a[i];
	}
	
	if (tot & 1) // 如果和是奇数则无法分成两半
	{
		printf("0");
		return 0;
	}
	tot >>= 1;
	memset(f, -1, sizeof (f));
	
	printf("%d", dfs(tot, 0) >> 1);
	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/drtlstf/article/details/83474522