Partition a set of numbers into two so that difference between their sum is minimum with equal size

265 篇文章 1 订阅
86 篇文章 0 订阅
Partition a set of numbers into two such that difference between their sum is minimum, and both sets have equal number of elements. 

For example: {1, 4, 9, 16} is partitioned as {1,16} and {4,9} with diff = 17-13=4. 

Does greedy work here? First sorting, and then picking smallest and largest to fall in set 1, and picking 2nd smallest and 2nd largest to fall in set 2. 

I was asked to prove which I failed :(

----------------------------------------------------------------------------------------------------

The problem is similar to knapsack problem, however, the number of knapsack is constant in this problem, so :

Observing the insanity of above posts which claim to develop a greedy O(nlogn) solution for a variation of partition problem, I was compelled to code the program. Being NP-hard by nature, the solution falls into pseudo-polynomial time algorithm with complexity O(n^2W) where n = # of elements, W = sum of elements.

//constraints: n is even
void fun (int items[], int n)
{
  int total = accumulate (items, items+n, 0) / 2;
  int maxSubsetSz = n/2 ;
	
  vector< vector<int> > T (maxSubsetSz+1, vector<int> (total+1, 0) );

  //T[i][j] is set if there exists subset of size i that sum up to j
  T[0][0] = 1;	

  for(int i = 0; i < n; i++) //consider taking i-th item 		
    for(int k = maxSubsetSz-1; k >= 0; k--) //each item must be taken once, hence loop backwards
      for(int j = 0; j <= total-items[i]; j++)  
        if ( T[k][j] && items[i]+j <= total )		      		    
          T[k+1][j+items[i]] = 1;

  for(int j = total; j >= 1; j--)
    if ( T [maxSubsetSz][j] ) {
      cout << "sum : " << j << endl; 
      break;
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值