一个整数数组,长度为n,将其分为m份,使各份的和相等,求m的最大值

本文代码参考网址:http://blog.csdn.net/v_july_v/article/details/6870251

 

问题描述:一个整数数组,长度为n,将其分为m 份,使各份的和相等,求m 的最大值
比如{3,2,4,3,6} 可以分成{3,2,4,3,6} m=1;
{3,6}{2,4,3} m=2
{3,3}{2,4}{6} m=3 所以m 的最大值为3

 

算法分析:

初始值m从n开始,依次递减测试;数组的和为sum,若sum%m的值不为0,则直接跳过
对于符合sum%m = 0的每个m,扫描数组中每个元素,若该元素的状态为未选,将其分配到相应组
(1) 若当前组元素的和大于 sum/m,表明当前元素不适合该组,将其状态(aux[i])置为0
(2) 若当前组元素的和等于 sum/m, 将组号加1,继续进行下一组的判断
(3) 若当前组元素的和小于 sum/m,将当前加入的元素置为已选状态(aux[i]的值设为当前组号),继续判断下一个元素加入加入当前组的情况

#include 
#include 

#define NUM	10

int maxShares(int a[], int n);

//aux[i]的值表示数组a中第i个元素分在哪个组,值为0表示未分配
//当前处理的组的现有和 + goal的值 = groupsum
int testShares(int a[], int n, int m, int sum, int groupsum, int aux[], int goal, int groupId);

int main()
{
	int a[] = {2, 6, 4, 1, 3, 9, 7, 5, 8, 10};

	//打印数组值
	printf("数组的值:");
	for (int i = 0; i < NUM; i++)
		printf(" %d ", a[i]);

	printf("\n可以分配的最大组数为:%d\n", maxShares(a, NUM));

	system("pause");
	return 0;
}

int testShares(int a[], int n, int m, int sum, int groupsum, int aux[], int goal, int groupId) 
{
	if (goal < 0)
		return 0;

	if (goal == 0)
	{
		groupId++;
		goal = groupsum;

		if (groupId == m+1)		
			return 1;
	}

	for (int i = 0; i < n; i++) 
	{
		if (aux[i] != 0)
			continue;

		aux[i] = groupId;
		if (testShares(a, n, m, sum, groupsum, aux, goal-a[i], groupId)) 
			return 1;

		aux[i] = 0;				//a[i]分配失败,将其置为未分配状态
	}

	return 0;
}
int maxShares(int a[], int n)
{
	int sum = 0;
	int *aux = (int *)malloc(sizeof(int) * n);			

	for (int i = 0; i < n; i++) 
		sum += a[i];

	for (int m = n; m >= 2; m--) 
	{
		if (sum%m != 0) 
			continue;

		for (int i = 0; i < n; i++) 
			aux[i] = 0;

		if (testShares(a, n, m, sum, sum/m, aux, sum/m, 1))
		{
			//打印分组情况
			printf("\n分组情况:");
			for (int i = 0; i < NUM; i++)
				printf(" %d ", aux[i]);

			free(aux);
			aux = NULL;
			return m;
		}
	}

	free(aux);
	aux = NULL;
	return 1;
}


你可能感兴趣的:(数据结构与算法)