題目描述:對於有n個數的數組,分爲兩組,這兩組的數的個數儘量相等(不超過1),同時兩組的數之和的差值最小。數組
這個題目使用相似0-1揹包問題,思路:從k個數中選i個數,求全部可能的和,並把這些和放在flag中用true表示。(k,i,flag見代碼)測試
1 public static void main(String[] args){ 2 int[] arr = {1 , 2 , 3 , 5 , 7 , 8 , 9}; 3 int n = 7; 4 int sum = 0; 5 for(int i:arr){ 6 sum += i; 7 } 8 boolean[][] flag = new boolean[n/2+1][sum/2+1]; 9 for(int i=0;i<n/2+1;i++){ 10 for(int j=0;j<sum/2+1;j++){ 11 flag[i][j] = false; 12 } 13 } 14 flag[0][0] = true; 15 for(int k = 0;k<n;k++){ 16 for(int i=k>n/2?n/2:k;i>=1;i--){ 17 //遍歷s(k,i) 18 for(int j=0;j<=sum/2;j++){ 19 if(j>=arr[k]&&flag[i-1][j-arr[k]]){ 20 flag[i][j] = true; 21 } 22 } 23 } 24 } 25 for(int i = sum/2;i>=0;i++){ 26 if(flag[n/2][i]) { 27 System.out.println(i); 28 break; 29 } 30 } 31 }
我以爲比較難理解的地方就是flag[i-1]這一行是什麼意思:表明從k中取i-1個數,他們的各類和的可能的體現(存在即爲true)spa
最裏面一層循環的意思是:從i-1這一行中取各類和 而後加上arr[k]湊成i個數的和,體如今flag[i]裏面。code
第二層循環的意思是:執行1-i這麼多行blog
最外面一層就是不斷往裏面加數。io
我測試的例子很少,可能有遺漏的地方,請留言指出來,難以理解的地方也能夠留言討論。class