zoukankan      html  css  js  c++  java
  • 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)

    最里面一层循环的意思是:从i-1这一行中取各种和 然后加上arr[k]凑成i个数的和,体现在flag[i]里面。

    第二层循环的意思是:执行1-i这么多行

    最外面一层就是不断往里面加数。

    我测试的例子不多,可能有遗漏的地方,请留言指出来,难以理解的地方也可以留言讨论。

  • 相关阅读:
    云架构师进阶攻略(3)
    微服务化之服务拆分与服务发现
    终于有人把云计算、大数据和人工智能讲明白了!(1)
    JavaScript的数组详解
    html中给元素添加背景图片或者gif动图
    JavaScript的事件
    JavaScript的匿名函数
    JavaScript获取和操作html的元素
    JavaScript的条件运算符与条件语句
    JavaScript变量、数据类型、函数
  • 原文地址:https://www.cnblogs.com/kevin-lee123/p/11563466.html
Copyright © 2011-2022 走看看