关闭

数组分割

标签: 数组分割
362人阅读 评论(0) 收藏 举报
分类:

1. 简述

    有一个无序、元素个数为2n的正整数数组,要求:如何能把这个数组分割为元素个数为n的两个数组,并使两个子数组的和最接近?例如有如下数组,1,5,7,8,9,6,3,11,20,17。应该分割为1,3,11,8,20和5,7,9,6,17。

2. 思路

    方法一,暴力搜索,遍历每种分组方法,一共C(2N, N)种组合,复杂度是(2N!/N!),复杂度过高。

    方法二,动态规划,原题是要求求两个数组的和最近接,这等价于要求其中较小的和最接近与2n个正整数的和(设为SUM)的一半。因此,弱化题目,求这个最近接一半的且小于等于SUM/2数值,定义Heap[i],i<=N表示任意i个数能够构成的数值集合。初始化:Heap[0]= 0。更新代码:

for(int i=1; i<2*N; i++) { // 依次读取A[i]更新堆 
for(int j=min{i, N}; j>0; j--) // 更新引入A[i]后可能的元素个数的情况
for each v in Heap[j-1] // 对于引入A[i]的情况
insert(Heap[j], A[i]+v);
}

    关于insert次数,至多为2^(N-1),为什么是这个数我没想明白,总共感觉上应该是C(2N,N)次插入啊。

    方法三,复杂度主要是由于堆很大,原因是我们记录的是各种可能组合出的数值。如果SUM值不高,可以定义bool FLAG[i][j],i=0,1,...,2*N,j=0,1,...,SUM/2,表示是否存在i个数,其和为j。初始化,FLAG[0][0] = true。

复制代码
for(int k=1; k<2*N; k++) {
for(int i=min{k, N}; i>0; i--) { // 每一个可能的长度
for(int v=1; v<SUM/2; v++) { // 每一个可能的可能的数值
if(v>=A[k] && FLAG[i-1][v-A[k]])
FLAG[i-1][v-A[k]] = true;
}
}
}
复制代码

    Max{j},其中,j=0,1,...,2*N,FLAG[N][j]=true,这即为所求。这样复杂度为O(N*N*SUM)级别的,尤其是当SUM相对不大的时候,复杂度会大大降低。

public class Array_cut 
{
	public static void main(String[] args)
	{
		int[] a={1,2,3,4,5,6,7,8};
		compute(a);
	}
	public static void compute(int[] a)
	{
		int sum=0;
		for(int i=0;i<a.length;i++)
			sum = sum+a[i];
		int n=a.length;
		boolean isOk[][] = new boolean[a.length/2+1][sum];
		isOk[0][0]=true;


		for(int i=1;i<isOk.length;i++)
		{
			for(int j=1;j<isOk[0].length;j++)
			{
				isOk[i][j]=false;
			}
		}
		for(int k=1;k<=a.length;k++)
		{
			for(int i=Math.min(k, a.length/2);i>=1;i--)
			{
				for(int v=1;v<=sum/2;v++)
				{
					//System.out.print("k="+k+"i="+i+"v="+v);
					if(v>=a[k-1]&&isOk[i-1][v-a[k-1]])
					{
						isOk[i][v]=true;
					}
				}
			}
		}
		print(isOk,a.length/2);
	}
	public static void print(boolean[][] a,int n)
	{
		for(int i=n;i<a.length;i++)
		{
			for(int j=1;j<a[0].length;j++)
			{
				System.out.print(a[i][j]+" ");
			}
			
		}
	
	}
}
结果如下:

false false false false false false false false false true true true true true true true true true false false false false false false false false false false false false false false false false false 

可以看出来,从中选4个数得到16,17,18都可以。

原文链接:http://www.cnblogs.com/pangxiaodong/archive/2011/10/10/2205366.html

3. 参考

    编程之美,2.18节,数组分割

0
0
查看评论

算法之--数组分割

题目来源:编程之美2.18 有一个无序的,元素个数为2n的正整数的数组,要求: 如何能把这个数组分割为元素个数为n的两个数组,使得两个子数组的和尽量接近。 解析:因为两个子数组的和是一定的,等于整个数组的和。现在要求使得两个字数组的和尽量的接近,也就意味着要从其中选出n个数使得这n个数的和尽可能...
  • C12345SDN
  • C12345SDN
  • 2014-08-07 14:49
  • 1114

编程之美 - 数组分割

问题: 有一个没有排序,有2N个元素的数组,要求把这个数组分为两部分,分别含有N个元素,并使两个子数组的和最接近。 这里的程序主要是计算这个和的值。 比如数组 {1, 10, 100, 1000},计算后符合的分法是 {1, 1000} {10, 100}...
  • wangzhiyu1980
  • wangzhiyu1980
  • 2016-07-02 19:28
  • 849

<编程之美>数组分割问题

题目概述:有一个没有排序,元素个数为2N的正整数数组。要求把它分割为元素个数为N的两个数组,并使两个子数组的和最接近。 假设数组A[1..2N]所有元素的和是SUM。模仿动态规划解0-1背包问题的策略,令S(k, i)表示前k个元素中任意i个元素的和的集合。显然:S(k, 1) = {A[i] |...
  • sushauai
  • sushauai
  • 2016-03-22 11:04
  • 272

编程之美2.18——数组分割

问题: 1. 有一个无序、元素个数为2n的正整数数组,要求:如何能把这个数组分割为两个子数组,子数组的元素个数不限,并使两个子数组之和最接近。 2. 有一个无序、元素个数为2n的正整数数组,要求:如何能把这个数组分割为元素个数为n的两个数组,并使两个子数组之和最接近。 1. ...
  • linyunzju
  • linyunzju
  • 2012-07-10 00:20
  • 10237

python numpy操作数组学习笔记(二)数组的分割和组合

这是我个人的学习笔记,如果看到有什么错误,请在评论里随意嘲笑我这个小白>< 这篇文章是接python初学者学习笔记(二)数组的操作的,都是使用numpy模块 一、数组的水平组合import numpy as npb = [[3, 2, 1], [6, 5, 4], [9, 8,...
  • weixin_37608233
  • weixin_37608233
  • 2017-03-27 22:59
  • 250

C# 拆分 合并 数组

//拆分任意类型数组 List SplitArray(T[] data, int size) { List list = new List(); for (int i = 0; i < data.Length / size; i++) { ...
  • leekumbong
  • leekumbong
  • 2014-06-10 16:26
  • 3852

数组分割

有一个没有排序、元素个数为2n的正整数数组,要求:如何能把这个数组分割为元素个数为n的两个数组,并使两个子数组的和最接近?(变相的背包问题,01背包问题(非完全背包问题),还是有点出入,这边要求个数是n)     2n个正整数数组好比财宝,数组和的一半表示背包容量,为...
  • xflame
  • xflame
  • 2013-08-19 16:31
  • 449

编程之美-数组分割方法整理

【试题描述】 方法一: 方法二:时间复杂度O(2^n) 方法三:时间复杂度O(n^2 * Sum)
  • GarfieldEr007
  • GarfieldEr007
  • 2015-11-09 20:13
  • 511

【编程之美】数组分割问题

一,问题:       1. 有一个无序、元素个数为2n的正整数数组,要求:如何能把这个数组分割为两个子数组,子数组的元素个数不限,并使两个子数组之和最接近。       2. 有一个无序、元素个数为2n的正整数数组,要求:如何能把这个...
  • tianshuai11
  • tianshuai11
  • 2012-08-03 22:25
  • 3242

asp split 分割二维数组

http://blog.sina.com.cn/s/blog_690a5d2301015kh8.html BL   =  "0023,元素2,1.34-0003,元素5,1.05-0014,元素1,0.02 " b   =  ...
  • liuxiaojun828
  • liuxiaojun828
  • 2015-11-04 14:52
  • 261
    个人资料
    • 访问:103462次
    • 积分:1953
    • 等级:
    • 排名:千里之外
    • 原创:93篇
    • 转载:43篇
    • 译文:0篇
    • 评论:8条
    最新评论