• 【子集或者DFS】部分和问题


    题目:

      给定整数序列a1,a2,...,an,判断是否可以从中选出若干数,使它们的和恰好为k。1≤n≤20   -108≤ai≤108   -108≤k≤108
      输入:

    n=4
    a={1,2,4,7}
    k=13

      输出:

    Yes (13 = 2 + 4 + 7)

    思路:

      这里记录一下为什么会想到用子集去做这道题目,这道题目是关于从几个数中找出几个关于符合某种关系的数,呐,根据模式匹配法很容易想到这种方法,而关于这种方法也可以推广开来,也就是说只要在n个数据中找几个数据都可以用求子集的方式去做。

    代码:

     1 import java.util.ArrayList;
     2 import java.util.Arrays;
     3 import java.util.Scanner;
     4 
     5 public class 部分和 {
     6 
     7     private static int kk;
     8     
     9     public static void main(String[] args) {
    10         Scanner sc = new Scanner(System.in);
    11         int n = sc.nextInt();
    12         int[] A = new int[n];
    13         for (int i = 0; i < n; i++) {
    14           A[i] = sc.nextInt();
    15         }
    16         int k = sc.nextInt();//13
    17         
    18         System.out.println("================解法一=============");
    19         ArrayList<ArrayList<Integer>> subsets = getSubsets(A, A.length);
    20         int count = 0;
    21         for (int i = 0; i < subsets.size(); i++) {
    22             for (int j = 0; j < subsets.get(i).size(); j++) {
    23                 count += subsets.get(i).get(j);
    24                 
    25                 if (count==k&&j==subsets.get(i).size()-1) {
    26                     System.out.println("yes k = "+subsets.get(i));
    27                 }
    28             }
    29             count = 0;  // 如果没找到 要将count置为0
    30         }
    31 //        System.out.println(subsets);
    32         
    33         System.out.println("================解法二=============");
    34         kk = k;
    35         dfs(A, k, 0, new ArrayList<Integer>());
    36     }
    37     /**
    38      * 本题最优解法  二进制求取所有子集然后求和等于k解决问题
    39      */
    40     public static ArrayList<ArrayList<Integer>> getSubsets(int []A,int n){
    41         Arrays.sort(A);  // 正序排序
    42         ArrayList<ArrayList<Integer>> res = new ArrayList<>();  //大集合
    43         for(int i = ex(2, n);i>0;i--){         //大数字-1
    44             ArrayList<Integer> s = new ArrayList<>();  //对每个i建立一个集合
    45             for(int j = n-1;j>=0;j--){    //检查哪个位上的二进制为1,从高位开始检查,高位对应着数组靠后的元素
    46                 if(((i>>j)&1)==1){
    47                     s.add(A[j]);
    48                 }
    49             }
    50             res.add(s);
    51         }
    52         // 生成的结果逆序排序,如果要生成正序排列,很难完成,只有数组反转实现。
    53         return res;
    54     }
    55     
    56     public static int ex(int a,int n){
    57         if(n==0)return 1;
    58         if(n==1)return a;
    59         int temp = a; // a的1次方
    60         int res = 1;
    61         int exponent = 1;
    62         while((exponent<<1)<n){
    63             temp = temp * temp;
    64             exponent = exponent << 1;
    65         }
    66         res *= ex(a,n-exponent);
    67         return res * temp;
    68     }
    69     
    70     private static void dfs(int[] a, int k, int cur, ArrayList<Integer> ints) {
    71         if (k == 0) {
    72             System.out.print("Yes (" + kk + " = ");
    73             int size = ints.size();
    74             for (int i = 0; i < size; i++) {
    75                 System.out.print(ints.get(i) + (i == size - 1 ? "" : " + "));
    76             }
    77             System.out.println(")");
    78             System.exit(0);
    79         }
    80         if (k < 0 || cur == a.length)
    81             return;
    82 
    83         dfs(a, k, cur + 1, ints);// 不要cur这个元素
    84 
    85         ints.add(a[cur]);
    86         int index = ints.size() - 1;
    87         dfs(a, k - a[cur], cur + 1, ints);
    88         ints.remove(index);// 回溯
    89     }
    90 }

    结果:

      

  • 相关阅读:
    用DD-WRT自建计费WiFi热点
    docker安全最佳实践概述
    2014年8月25日,收藏家和杀手——面向对象的C++和C(一)
    Maven
    做QA的日子——iOS測试入门(四)
    小贝_mysql select连接查询
    FFmpeg源码简单分析:结构体成员管理系统-AVOption
    Keepalived+nginx+redis主从+tomcat一机多实例实现会话共享
    Redis主从配置及通过Keepalived实现Redis自动切换高可用
    CentOS 安装jdk1.7 32位
  • 原文地址:https://www.cnblogs.com/xiaoyh/p/10346658.html
Copyright © 2020-2023  润新知