/*
45.雅虎:
2.一个整数数组,长度为 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
将整个数组作为一个集合,最大的可能值就是集合的大小了,最小肯定是1,
那么从2开始一次判断。如果集合可被k等分,
那么首先集合的和能够被k整除,条件满足,则重复k-1次从这个集合中取出和为sum/k的子集合。
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
bool testShare(int s[],int n,int m,int groupSum,int goal,int aux[],int groupId)
{
if(goal==0)// groupSum为每组的和,goal表示还剩多少,groupId现在是第几组
{
groupId++;//一组分配完,ID++,goal重置
goal=groupSum;
if (groupId==m+1)// 已经分完m组
return true;
}
for(int i=0;i<n;++i)
{
if(aux[i])
continue; //已经选过的
aux[i]=groupId;//标记这是放在第几组
if(testShare(s,n,m,groupSum,goal-s[i],aux,groupId))
//判断goal-s[i],可行否
return true;
aux[i]=0; //还原,继续下次
}
return false;
}
int maxShare(int s[],int len)
{
int i,m,sum=0;
int aux[len];
for(i=0;i<len;i++)
sum+=s[i]; //求总和
for(m=len;m>=2;--m)//m表示分成几组,递减
{
if(sum%m!=0) //不能被m整除,肯定不能平分
continue;
memset(aux,0,sizeof(aux));//aux表示分成不同的组
//testShare(s[],n, m, groupSum, goal, aux[], groupId)
if(testShare(s,len,m, sum/m,sum/m,aux,1))
{
printf("具体分配如下:\n");
for(i=1;i<=m;i++)
{
for(int j=0;j<len;j++)
if(aux[j]==i)
printf("%d ",s[j]);
if(i!=m)
printf(" , ");
}
printf("\n");
return m;
}
}
return 1;
}
int main()
{
int a[] ={5,4,2,2,1,4,6};
int b[] ={3,2,4,3,6,1,5,4,2,5,6,1};
int c[] ={3,2,4,3,6};
printf("数组的值:");
for(int i=0;i<sizeof(a)/sizeof(int);i++)
printf("%d ",a[i]);
printf("\n");
printf("可以分配的最大组数为:%d\n",maxShare(a,sizeof(a)/sizeof(int)));
printf("**************************************\n");
printf("数组的值:");
for(int i=0;i<sizeof(b)/sizeof(int);i++)
printf("%d ",b[i]);
printf("\n");
printf("可以分配的最大组数为:%d\n",maxShare(b,sizeof(b)/sizeof(int)));
printf("**************************************\n");
printf("数组的值:");
for(int i=0;i<sizeof(c)/sizeof(int);i++)
printf("%d ",c[i]);
printf("\n");
printf("可以分配的最大组数为:%d\n",maxShare(c,sizeof(c)/sizeof(int)));
}
45 整数数组,将其分为m份使各份的和相等
最新推荐文章于 2022-07-13 23:07:00 发布