题目:

  给定整数序列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个数据中找几个数据都可以用求子集的方式去做。

代码:

 import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner; public class 部分和 { private static int kk; public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] A = new int[n];
for (int i = 0; i < n; i++) {
A[i] = sc.nextInt();
}
int k = sc.nextInt();// System.out.println("================解法一=============");
ArrayList<ArrayList<Integer>> subsets = getSubsets(A, A.length);
int count = 0;
for (int i = 0; i < subsets.size(); i++) {
for (int j = 0; j < subsets.get(i).size(); j++) {
count += subsets.get(i).get(j); if (count==k&&j==subsets.get(i).size()-1) {
System.out.println("yes k = "+subsets.get(i));
}
}
count = 0; // 如果没找到 要将count置为0
}
// System.out.println(subsets); System.out.println("================解法二=============");
kk = k;
dfs(A, k, 0, new ArrayList<Integer>());
}
/**
* 本题最优解法 二进制求取所有子集然后求和等于k解决问题
*/
public static ArrayList<ArrayList<Integer>> getSubsets(int []A,int n){
Arrays.sort(A); // 正序排序
ArrayList<ArrayList<Integer>> res = new ArrayList<>(); //大集合
for(int i = ex(2, n);i>0;i--){ //大数字-1
ArrayList<Integer> s = new ArrayList<>(); //对每个i建立一个集合
for(int j = n-1;j>=0;j--){ //检查哪个位上的二进制为1,从高位开始检查,高位对应着数组靠后的元素
if(((i>>j)&1)==1){
s.add(A[j]);
}
}
res.add(s);
}
// 生成的结果逆序排序,如果要生成正序排列,很难完成,只有数组反转实现。
return res;
} public static int ex(int a,int n){
if(n==0)return 1;
if(n==1)return a;
int temp = a; // a的1次方
int res = 1;
int exponent = 1;
while((exponent<<1)<n){
temp = temp * temp;
exponent = exponent << 1;
}
res *= ex(a,n-exponent);
return res * temp;
} private static void dfs(int[] a, int k, int cur, ArrayList<Integer> ints) {
if (k == 0) {
System.out.print("Yes (" + kk + " = ");
int size = ints.size();
for (int i = 0; i < size; i++) {
System.out.print(ints.get(i) + (i == size - 1 ? "" : " + "));
}
System.out.println(")");
System.exit(0);
}
if (k < 0 || cur == a.length)
return; dfs(a, k, cur + 1, ints);// 不要cur这个元素 ints.add(a[cur]);
int index = ints.size() - 1;
dfs(a, k - a[cur], cur + 1, ints);
ints.remove(index);// 回溯
}
}

结果:

  

【子集或者DFS】部分和问题的更多相关文章

  1. [蓝桥杯]2015蓝桥省赛B组题目及详解

    /*——————————————————————————————————————————————————————————— [结果填空题]T1 题目:奖券数目 有些人很迷信数字,比如带“4”的数字,认 ...

  2. COGS 513 八

    513. 八 http://www.cogs.pro/cogs/problem/problem.php?pid=513 ★☆   输入文件:eight.in   输出文件:eight.out   简单 ...

  3. nyoj 1058部分和问题(DFS)

    部分和问题 时间限制:1000 ms  |  内存限制:65535 KB 难度:2   描述 给定整数a1.a2........an,判断是否可以从中选出若干数,使它们的和恰好为K.   输入 首先, ...

  4. 部分和问题(dfs)

    部分和问题 时间限制:1000 ms  |           内存限制:65535 KB 难度:2   描述 给定整数a1.a2........an,判断是否可以从中选出若干数,使它们的和恰好为K. ...

  5. 深度优先搜索(DFS)——部分和问题

    对于深度优先搜索,这里有篇写的不错的博客:DFS算法介绍 .总得来说是从某个状态开始,不断的转移状态知道无法转移,然后回到前一步的状态.如此不断的重复一直到找到最终的解.根据这个特点,常常会用到递归. ...

  6. 78. Subsets(中等,集合的子集,经典问题 DFS)

    Given a set of distinct integers, nums, return all possible subsets. Note: The solution set must not ...

  7. POJ-3279.Fliptile(二进制状态压缩 + dfs) 子集生成

    昨天晚上12点刷到的这个题,一开始一位是BFS,但是一直没有思路.后来推了一下发现只需要依次枚举第一行的所有翻转状态然后再对每个情况的其它田地翻转进行暴力dfs就可以,但是由于二进制压缩学的不是很透, ...

  8. UVA 1508 - Equipment 状态压缩 枚举子集 dfs

    UVA 1508 - Equipment 状态压缩 枚举子集 dfs ACM 题目地址:option=com_onlinejudge&Itemid=8&category=457& ...

  9. NYOJ 1058 部分和问题 【DFS】

    部分和问题 时间限制:1000 ms  |  内存限制:65535 KB 难度:2 描写叙述 给定整数a1.a2........an,推断能否够从中选出若干数.使它们的和恰好为K. 输入 首先,n和k ...

随机推荐

  1. gardner 算法matlab实现

    % 仿真4比特原始数据与星座图的编码映射过程: % 完成16QAM信号的调制解调: % 基带信号符号速率 ps =1Mbps: % 成形滤波器的滚降因子 a=0.8: % 载波信号频率fc=2MHz ...

  2. linux yum提示Loaded plugins: fastestmirror, security错误的解决方法

    别听网上的,先检查自己是不是打错了.........我就是打错了一个横杆搞了一个多小时 具体: 如图这种,长横杆 修改后结果: 所以在不知情的情况之下千万不要乱改东西,先检查代码是否有误 题外话: = ...

  3. mysql 函数学习(常用)

    1.时间函数(组1) SELECT CURRENT_DATE() AS date, CURRENT_TIME() AS `time`, CURRENT_TIMESTAMP() AS `timestam ...

  4. java 动态代理模式(jdk和cglib)

    package proxy.dynamicproxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Met ...

  5. 函数式编程-compose与pipe

    函数式编程中有一种模式是通过组合多个函数的功能来实现一个组合函数.一般支持函数式编程的工具库都实现了这种模式,这种模式一般被称作compose与pipe.以函数式著称的Ramda工具库为例. cons ...

  6. Webpack 开发服务器代理设置解决跨域问题

    在前端开发过程中,可能会遇到跨域问题,在 webpack 设置中对 devServer 配置代理即可解决跨域问题,具体设置如下: webpack.config.js module.exports = ...

  7. Redis持久化persistence

    一.前言 由于Redis的数据都存放在内存中,如果没有配置持久化,redis重启后数据就全丢失了,于是需要开启redis的持久化功能,将数据保存到磁盘上,当redis重启后,可以从磁盘中恢复数据. R ...

  8. ES6---箭头函数()=>{} 与function的区别(转载)

    1.箭头函数与function定义函数的写法: //function function fn(a, b){ return a + b; } //arrow function var foo = (a, ...

  9. hibernate-release-5.2.9.Final

    链接:https://pan.baidu.com/s/1UaoaaXb5C9gJp3Yu7sjUVQ 提取码:orgx

  10. tomcat运行后提示Could not create the Java Virtual Machine.

    大致的问题是Java虚拟机(JVM)分配的内存大于系统可用内存,一开始去网上找了些资料,大多是都是说修改MyEclipse安装目录下的elicpse.ini文件中的内存大小.但我试了之后发现然并软,后 ...