n個數分爲兩組,兩組數的個數儘量相等,差值最小

題目描述:對於有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

相關文章
相關標籤/搜索