回溯算法示例(固定元组)

固定元组和可变元组是基于解的表达形式,固定元组使用0、1表示某元素是否存在,可变元组则直接给出可行解包含的元素。使用回溯算法解决子集求和问题的示例如下:

public class SumOfSub {
	int[] x;// 固定元组
	float[] w;//权值
	float m;//和

	public SumOfSub(int n, float[] w, float m) {
		x = new int[n + 1];
		this.w = w;
		this.m = m;
	}

	public void solve(float s, int k, float r) {
		x[k] = 1;
		if (s + w[k] == m) {
			for (int j=1;j<=k;j++) 	System.out.print(x[j]+" ");
			System.out.println();
		} else if (s + w[k] + w[k + 1] <= m) solve(s + w[k], k + 1, r - w[k]);
		if (s + r - w[k] >= m&& s + w[k + 1] <= m ) {
			x[k] = 0;
			solve(s, k + 1, r - w[k]);
		}
	}

	public static void main(String[] args) {
		float[] w = { 0, 5, 10, 12, 13, 15, 18 };
		SumOfSub a = new SumOfSub(6, w, 30);
		a.solve(0, 1, 73);
	}
}

w数组默认为严格递增。注意到一开始s+r=0+r>m,而每层递归调用时皆满足s + w[k + 1] <= m ;每次调用时必定有s+r>=m,因为如果没有进入过右子树,则s+r不变大于m,如果进入过右子树,则由生成右子树的判定s + r - w[k] >= m知s+r>=m。所以由 {   s + w [ k + 1 ] < = m   s + r > = m   s ! = m \begin{cases} \ s + w[k + 1] <= m\\ \ s+r>=m\\ \ s!=m \end{cases}  s+w[k+1]<=m s+r>=m s!=m

{   s + w [ k ] < m   s + r > = m   r ! = 0 \begin{cases} \ s + w[k] < m\\ \ s+r>=m\\ \ r!=0 \end{cases}  s+w[k]<m s+r>=m r!=0
进而有
{   r ! = w [ k ]   r ⩾ w [ k ] + w [ k + 1 ]   k + 1 ⩽ n \begin{cases} \ r!=w[k] \\ \ r \geqslant w[k]+w[k+1] \\ \ k+1⩽ n \end{cases}  r!=w[k] rw[k]+w[k+1] k+1n
保证了数组不会越界。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值