一个整数数组,长度为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

问题描述:一个整数数组,长度为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等份,则数组的和对m取余数肯定为0,且m的取值范围为1<m<=n,既然
 * 求m的最大值,则让m从n开始递减,第一个满足条件的即为m的最大取值。设数组为a,
 * 数组的和为sum,设一临时数组temp来存储分组情况,groupID表示分组编号
 * 比如temp[i]=1,则说明a[i]分在第一组。
 * 当sum%m不等于0时,跳过,m递减;当sum%m等于0时,遍历数组中每个元素,若当前
 * 元素状态为未选择,即temp[i]=0,将其分配到相应组中,进行如下判断:
 * a.若组内元素和>sum/m,则说明当前元素不适合加入该组,令temp[i]=0;
 * b.若组内元素和=sum/m,则令groupID++,继续遍历,判断下一组;
 * c.若组内元素和<sum/m,则将当前元素状态改为已选,temp[i]=组号,继续进行下
 * 一个元素的判断;
 * 则满足条件的第一个m值即为最大的。

代码实现:

public class fraction {

	/**
	 * @param PLA
	 *            问题描述:一个整数数组,长度为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等份,则数组的和对m取余数肯定为0,且m的取值范围为1<m<=n,既然
	 * 求m的最大值,则让m从n开始递减,第一个满足条件的即为m的最大取值。设数组为a,
	 * 数组的和为sum,设一临时数组temp来存储分组情况,groupID表示分组编号 比如temp[i]=1,则说明a[i]分在第一组。
	 * 当sum%m不等于0时,跳过,m递减;当sum%m等于0时,遍历数组中每个元素,若当前
	 * 元素状态为未选择,即temp[i]=0,将其分配到相应组中,进行如下判断:
	 * a.若组内元素和>sum/m,则说明当前元素不适合加入该组,令temp[i]=0;
	 * b.若组内元素和=sum/m,则令groupID++,继续遍历,判断下一组;
	 * c.若组内元素和<sum/m,则将当前元素状态改为已选,temp[i]=组号,继续进行下 一个元素的判断; 则满足条件的第一个m值即为最大的。
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int[] a = { 3, 2, 4, 3, 6 };
		int n = a.length;
		System.out.println("原数组:");
		for (int i : a) {
			System.out.println(i + " ");
		}
		getMax(a, n);
	}

	private static void getMax(int[] a, int n) {
		// TODO Auto-generated method stub
		int sum = 0;
		int[] temp = new int[n];// 用于记录数组中当前元素的分组状态
		for (int i : a) {
			sum += i;
		}
		for (int m = n; m > 1; m--) {
			if (sum % m != 0)
				continue;
			for (int j = 0; j < n; j++) {
				temp[j] = 0;
			}
			if (Test(a, n, m, sum / m, temp, sum / m, 1)) {
				System.out.println("The Max m is:" + m);
				break;
			}
		}
	}

	private static boolean Test(int[] a, int n, int m, int groupSum,
			int[] temp, int total, int groupID) {
		// TODO Auto-generated method stub
		if (total < 0) {// 说明加上当前元素后数小组元素的和过大
			return false;
		}
		if (total == 0) {
			groupID++;
			total = groupSum;
			if (groupID == m + 1) {
				return true;
			}
		}
		for (int i = 0; i < n; i++) {
			if (temp[i] != 0)
				continue;
			temp[i] = groupID;
			if (Test(a, n, m, groupSum, temp, total - a[i], groupID))
				return true;
			temp[i] = 0;// 当前元素分配失败,置回初始状态
		}
		return false;
	}
}
运行结果:

原数组:
3 
2 
4 
3 
6 
The Max m is:3



  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值