回溯法---子集和问题(6)

body
{
font-family: 微软雅黑,"Microsoft YaHei", Georgia,Helvetica,Arial,sans-serif,宋体, PMingLiU,serif;
font-size: 10.5pt;
line-height: 1.5;
}
html, body
{

}
h1 {
font-size:1.5em;
font-weight:bold;
}
h2 {
font-size:1.4em;
font-weight:bold;
}
h3 {
font-size:1.3em;
font-weight:bold;
}
h4 {
font-size:1.2em;
font-weight:bold;
}
h5 {
font-size:1.1em;
font-weight:bold;
}
h6 {
font-size:1.0em;
font-weight:bold;
}
img {
border:0;
max-width: 100%;
height: auto !important;
}
blockquote {
margin-top:0px;
margin-bottom:0px;
}
table {
border-collapse:collapse;
border:1px solid #bbbbbb;
}
td {
border-collapse:collapse;
border:1px solid #bbbbbb;
}

问题描述:

在给定的集合中挑选出所有和为C的子集和。

在(2)的算法框架基础上:

import java. util.Vector ;

public class Subset extends CombineProblem {

int[] arr ;

int c;

public Subset(int[] arr , int c, int n) {

this.flag = false ;

this.n = n;

this.x = new Integer[n];

this.arr = arr;

this.c = c;

}

@Override

public Vector<Comparable> makeIterm (int k) {

Vector vec = new Vector();

for ( int i = 0 ; i <= 1 ; i++) {

vec .add( i);

}

return vec;

}

@Override

public boolean complete(int k) {

int sum = 0 ;

if ( k >= n)

for ( int i = 0 ; i < n; i++) {

sum += ( arr[i ] * (Integer) x [i]);

}

return sum == c;

}

@Override

public void printsolution(int k) {

for ( int i = 0 ; i < n; i++) {

if (( Integer) x [i] == 1) {

System .out. print(arr [i] + " ");

}

}

System .out. println("" );

}

@Override

public boolean isPartial(int k) {

int sum = 0 ;

for ( int i = 0 ; i < k; i++)

sum += ( arr[i ] * (Integer) x [i]);

return sum <= c;

}

}


主函数:


public class Main {

public static void main(String [] args) {

int[] arr = { 1 , 2 , 3 , 4 , 5 , 6 , - 1, -3, -5 };

Problem p = new Subset(arr , 6 , arr. length);

p .explore(0);

if (! p.flag) {

System .out. println("no solution!" );

}

}

}


输出结果:


6

2 4

1 5

1 2 3

来自为知笔记(Wiz)

时间: 2024-11-06 05:08:53

回溯法---子集和问题(6)的相关文章

回溯法 子集树和排序树

当所给问题是从n个元素的集合S中找出满足某种性质的子集时,解空间为子集树.例如:0-1背包问题 当所给问题是从n个元素的集合S中找出满足某种性质的排列时,解空间为排列树.例如:旅行售货员问题 回溯法搜索子集树算法描述为: void backtrack(int  t) { if(t>n) output(x); else for(int i=0; i<=1; i++) { x[t] = i; if(constraint(t) && bound(t)) backtrack(t+1);

回溯法小实例

1.图的m着色问题: 1 /* 2 *问题描述:给定无向连通图G和m种不同的颜色.用这些颜色为图G的各个顶点着色,每个顶点着一种颜色.是否有一种着色法使G中每条边的两个顶点着不同的颜色. 3 * 这个问题是图的m可着色判定问题.若一个图最少需要m中颜色才能使图中每条边连接的2个顶点着不同的颜色,则称这个数m为该图的色数. 4 *算法分析:给定图G=(V,E)和m中颜色,如果这个图不是m可着色,给出否定回答:如果这个图是m可着色的,找出所有不同的着色法. 5 * 回溯法+子集树 6 * 问题的解空

ACM:回溯法,子集生成

(一)增量构造法 #include <iostream> #include <algorithm> using namespace std; const int MAXN = 1000; int A[MAXN], n; void print_subset(int n, int *A, int cur) { for(int i = 0; i < cur; ++i) cout << A[i] << " "; cout <<

回溯法 求集合全排列、子集

全排列: 全排列是将一组数按一定顺序进行排列,如果这组数有n个,那么全排列数为n!个. 从集合中依次选出每一个元素,作为排列的第一个元素,然后对剩余的元素进行全排列,如此递归处理,从而得到所有元素的全排列. 以对字符串abc进行全排列为例,我们可以这么做:以abc为例固定a,求后面bc的排列:abc,acb,求好后,a和b交换,得到bac固定b,求后面ac的排列:bac,bca,求好后,c放到第一位置,得到cba固定c,求后面ba的排列:cba,cab. 这个思想和回溯法比较吻合. 代码可如下编

看数据结构写代码(33) 树与回溯法(一) 子集树

回溯法 是 一种 在 穷举 中,裁剪 不满足 条件 的 分支,已达到 提高 效率的 方法.其基本原型 是 树的 先序遍历,从 树根 到 树叶的路径 是 问题的 一个 解. 回溯法的基本框架 =  确定 解空间 + 深度优先遍历 + 裁剪函数 + 确定结果函数 其中 解空间,分为 子集树 和 排序树. 具体 概念 详解:参考 点击打开链接  和 点击打开链接 递归算法通用 模板如下: 回溯法对解空间作深度优先搜索,因此,在一般情况下用递归方法实现回溯法. // 针对N叉树的递归回溯方法 void

回溯法 -数据结构与算法

1.回溯法算法思想: 定义: 回溯法(探索与回溯法)是一种选优搜索法,按选优条件向前搜索,以达到目标.但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”. 1.回溯法适用:有许多问题,当需要找出它的解集(全部解)或者要求回答什么解是满足某些约束条件的最优解时,往往要使用回溯法. 2.有组织的穷举式搜索:回溯法的基本做法是搜索或者有的组织穷尽搜索.它能避免搜索所有的可能性.即避免不必要的搜索.这种方

回溯法

递归回溯 由于回溯法是对解空间的深度优先搜索,因此在一般情况下可用递归函数来实现回溯法如下: t表示递归深度,即当前扩展节点在解空间树的深度. n用来控制递归深度.当t>n时表示算法搜索到叶节点. void backtrack( int t ) { if ( t>n ) output(x); else for( int i=f(n,t); i<=g(n,t); i++ ) { x[t]=h(i); if ( constraint(t)&&bound(t) ) backtr

回溯法-01背包问题之一:递归模式

一.回溯法 回溯法是一个既带有系统性又带有跳跃性的搜索算法.它在包含问题的所有解的解空间树中按照深度优先的策略,从根节点出发搜索解空间树.算法搜索至解空间树的任一节点时,总是先判断该节点是否肯定不包含问题的解.如果肯定不包含,则跳过对以该节点为根的子树的系统搜索,逐层向其原先节点回溯.否则,进入该子树,继续按深度优先的策略进行搜索. 运用回溯法解题通常包含以下三个步骤: · 针对所给问题,定义问题的解空间: · 确定易于搜索的解空间结构: · 以深度优先的方式搜索解空间,并且在搜索过程中用剪枝函

(回溯法)和为n的所有不增正整数和式分解算法

利用递归算法输出正整数和为n的所有不增的正整数和式.例如当n=5时,不增的和式如下: 5=5 5=4+1 5=3+2 5=3+1+1 5=2+2+1 5=2+1+1+1 5=1+1+1+1+1 形如这种求子集的问题都可以采用回溯法来解决,回溯法即一种加上剪枝判断的递归算法. 解决问题的关键词:不增 代码实现如下: 数组a用来保存分解出来的和数,即某个分解的集合 sum表示需要分解的数 k表示要分解的第k个和数 #include <iostream> #include <stdio.h&g