码迷,mamicode.com
首页 > 其他好文 > 详细

数组分割

时间:2014-09-06 21:15:03      阅读:324      评论:0      收藏:0      [点我收藏+]

标签:style   os   io   使用   ar   for   cti   sp   on   

将大小为2N的数组分成两个大小为N的数组,使得两个子数组之和最接近

#include<iostream>

using namespace std;

#define min(a,b) (((a)<=(b))?(a):(b))

void function(int arr[],int n)

{

int sum=0;

int i;

int rem;

int **isOK;

int k;

int v;

for (i=1;i<=2*n;i++)

{

sum += arr[i];

}

rem=sum/2;

isOK=(int **)malloc(sizeof(int*)*(n+3));

for (i=0;i<=n+1;i++)

{

isOK[i]=(int *)malloc(sizeof(int)*(sum+2));

memset(isOK[i],0,sizeof(isOK[i])*(sum+2));//动态分配内存之后初始化。

}

 

 

isOK[0][0]=1;

for (k=1;k<=2*n;k++)

{//对于前K个数的情况

for (i=1;i=min(k,n);i++)

//这里FOR循环I必须是递增,不能是递减,因为否则下面的isOK[i-1][v-arr[k]]会导致某个i会在前一个i-1中继续加上arr[k],导致arr[k]被使用两次

{

//这一层循环的目的在于对于正在考虑的元素arr[k],它加入进来后,该子集的个数是不确定的,因此需要逐步遍历考虑。可能前k个全部加入,也可能只是1k两个元素。

//从前K个数里面,选择i个数。当k>n时,表示考虑到了后面n个,但是最多只能取n个。这里考虑的是从2n中取出n个,并且使得这n个之和最接近sum/2

for (v=1;v<=rem;v++)

{

if (v>=arr[k]&&(isOK[i-1][v-arr[k]]))

//这里的i表示有多少个元素

当前只考虑是否把第k个元素是否加入进来

{

isOK[i][v]=1;

}

}

}

}

 

 

v=rem;

while (v>=1&&(!isOK[n][v]))

{

v--;

}

cout<<"两个数组的差为:"<<sum-2*v<<endl;

}

int main()

{

int n;

int *arr;

int i;

cout<<"请输入 n : ";

cin>>n;

arr=(int *)malloc(sizeof(int)*(n+2));

cout<<"请输入 "<<2*n<<"个数字:"<<endl;

for (i=1;i<=2*n;i++)

{

cin>>arr[i];

}

function(arr,n);

return 0;

}

数组分割

标签:style   os   io   使用   ar   for   cti   sp   on   

原文地址:http://www.cnblogs.com/notlate/p/3959782.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!