程式設計之美 2 18 陣列分割

2021-09-08 15:46:31 字數 942 閱讀 7838

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++) ; 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++) ; i>0; i--)     

}}

max,其中,j=0,1,...,2*n,flag[n][j]=true,這即為所求。這樣複雜度為o(n*n*sum)級別的,尤其是當sum相對不大的時候,複雜度會大大降低。

3. 參考

程式設計之美,2.18節,陣列分割

《程式設計之美》 2 18 陣列分割

題目概述 有乙個沒有排序,元素個數為2n的正整數陣列。要求把它分割為元素個數為n的兩個陣列,並使兩個子陣列的和最接近。假設陣列a 1.2n 所有元素的和是sum。模仿動態規劃解0 1揹包問題的策略,令s k,i 表示前k個元素中任意i個元素的和的集合。顯然 s k,1 s k,k s k,i s k...

程式設計之美 2 18 陣列分割

本人第一次寫部落格,如有不對,請多加指正。解法一的思路很明顯是錯的。貪心演算法很多情況下求不出最佳解答,因為可能兩個陣列間需要同時交換兩個或者兩個以上的數,才能實現差值最小。如 解法二的思路將也就是乙個組合的問題在2n個陣列中找出n個數,使得n個數之和最接近於sum 2,這裡取小於等於sum 2的情...

《程式設計之美》 2 18 陣列分割

題目概述 有乙個沒有排序,元素個數為2n的正整數陣列。要求把它分割為元素個數為n的兩個陣列,並使兩個子陣列的和最接近。假設陣列a 1.2n 所有元素的和是sum。模仿動態規劃解0 1揹包問題的策略,令s k,i 表示前k個元素中任意i個元素的和的集合。顯然 s k,1 s k,k s k,i s k...