数组分割问题解法上总体来说就是用动态规划的方法求出2n个数中,取出n个数相加所能得到的所有的值,然后从中找到最接近sum/2的那个值。解法一中,每一步都需要更新每一个Heap中的每一个元素,而Heap中的元素个数随着K的增大而增大;解法二不再遍历Heap中的元素,而是遍历1---sum/2之间的值。解法二用了一个二维数组isOK来保存结果,isOK[i][j]表示能否找到i个数,使得他们的和等于j。下面是用解法二实现的源代码,如果要获得数组分割的具体分法,仍然可以用建立对象来保存索引的方法。
/*This is program will the sum of n elements which is close to the half the sum of 2*n elemens input: an array having 2*n elements output: the sum close to the half the sum of 2*n elements */ #include <stdio.h> #include <stdlib.h> void main() { int a[] = {1,5,7,8,9,6,3,11,20,17}; int n = sizeof(a)/sizeof(int)/2; int sum = 0; int i,j,k,v; for(i=0;i<2*n;i++) sum += a[i]; int **isOK = malloc(sizeof(int *)*(n+1)); for(i=0;i<n+1;i++){ isOK[i] = malloc(sizeof(int)*(sum/2+1)); } for(i=0;i<(n+1);i++) for(j=0;j<(sum/2+1);j++) isOK[i][j] = 0; isOK[0][0] = 1; for(k=1;k<=2*n;k++){ int updateIndex = min(k,n); for(j=updateIndex;j>=1;j--){ for(v=1;v<=sum/2;v++){ if(a[k-1]<=v && isOK[j-1][v-a[k-1]]) isOK[j][v] = 1; } } } for(i=sum/2;i>=0;i--){ if(isOK[n][i]==1){ printf("%d\n",i); break; } } } int min(int x, int y) { return x<y?x:y; }