【子集或者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个数据中找几个数据都可以用求子集的方式去做。
代码:
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】部分和问题的更多相关文章
- [蓝桥杯]2015蓝桥省赛B组题目及详解
/*——————————————————————————————————————————————————————————— [结果填空题]T1 题目:奖券数目 有些人很迷信数字,比如带“4”的数字,认 ...
- COGS 513 八
513. 八 http://www.cogs.pro/cogs/problem/problem.php?pid=513 ★☆ 输入文件:eight.in 输出文件:eight.out 简单 ...
- nyoj 1058部分和问题(DFS)
部分和问题 时间限制:1000 ms | 内存限制:65535 KB 难度:2 描述 给定整数a1.a2........an,判断是否可以从中选出若干数,使它们的和恰好为K. 输入 首先, ...
- 部分和问题(dfs)
部分和问题 时间限制:1000 ms | 内存限制:65535 KB 难度:2 描述 给定整数a1.a2........an,判断是否可以从中选出若干数,使它们的和恰好为K. ...
- 深度优先搜索(DFS)——部分和问题
对于深度优先搜索,这里有篇写的不错的博客:DFS算法介绍 .总得来说是从某个状态开始,不断的转移状态知道无法转移,然后回到前一步的状态.如此不断的重复一直到找到最终的解.根据这个特点,常常会用到递归. ...
- 78. Subsets(中等,集合的子集,经典问题 DFS)
Given a set of distinct integers, nums, return all possible subsets. Note: The solution set must not ...
- POJ-3279.Fliptile(二进制状态压缩 + dfs) 子集生成
昨天晚上12点刷到的这个题,一开始一位是BFS,但是一直没有思路.后来推了一下发现只需要依次枚举第一行的所有翻转状态然后再对每个情况的其它田地翻转进行暴力dfs就可以,但是由于二进制压缩学的不是很透, ...
- UVA 1508 - Equipment 状态压缩 枚举子集 dfs
UVA 1508 - Equipment 状态压缩 枚举子集 dfs ACM 题目地址:option=com_onlinejudge&Itemid=8&category=457& ...
- NYOJ 1058 部分和问题 【DFS】
部分和问题 时间限制:1000 ms | 内存限制:65535 KB 难度:2 描写叙述 给定整数a1.a2........an,推断能否够从中选出若干数.使它们的和恰好为K. 输入 首先,n和k ...
随机推荐
- Typescript---03 类、接口、枚举
传统的javascript程序使用函数和基于原型的继承来创建可重用的组件,从ECMAScript2015(ECMAScript 6)开始,可以使用基于类的面向对象方式. 一.类: 定义类(class) ...
- bzoj 3697
题目描述:这里 发现还是点对之间的问题,于是还是上点分 只不过是怎么做的问题 首先对每条边边权给成1和-1(即把原来边权为0的边边权改为-1),那么合法的路径总权值一定为0! 还是将路径分为经过当前根 ...
- 认识 Linux 文件权限
Linux 之所以是比较安全的操作系统,和它丰富的文件权限设定是有关系的,学习 Linux 操作系统一定要懂文件的权限识别和设置.通过这篇博文我们了解 Linux 操作系统的文件权限. 拥有者 / ...
- Python学习笔记十二
HTML全称:Hyper Text Markup Language超文本标记语言 不是编程语言 HTML使用标记标签来描述网页 2. HTML标签 开始标签,结束标签. 例如:<html&g ...
- elsticsearch在kibanna中的操作
#建立索引 PUT /es_note_tel{ "settings": { "number_of_shards": 1 }, "mappings&qu ...
- JAVA BigDecimal 用法
一.BigDecimal 的加减乘除 BigDecimal bignum1 = new BigDecimal("10"); BigDecimal bignum2 = new Big ...
- MySQL 常用命令(Linux)
一.查看MySQL服务 MySQL服务应该随开机自动启动的.正常情况下,查看开机自动启动的服务使用chkconfig命令,如下: chkconfig --list 实际mysql是否真正启动,是否真正 ...
- 手把手带你入门kubernetes部署
实验环境准备 k8s-master 192.168.2.156 k8s-node节点 192.168.2.161 Ps:两台保证时间同步,firewalld防火墙关闭,selinxu关闭,系统 ...
- call_user_func 与call_user_func_array 的使用与区别
1 call_user_func 的使用 1)使用方法直接传递值 function nowamagic($a,$b){ echo $a; echo $b; } call_user_func('nowa ...
- x64类型的程序逆向思考
x64类型比较习惯ida去分析,需要注意的是在x64程序中,有时会因为自己对寄存器不太熟悉导致自己分析过程混淆,下面坐下简单记录