算法设计与分析: 5-1 子集和问题

5-1 子集和问题


问题描述

子集和问题的一个实例为 S,t 〈 S , t 〉 。其中, S={x1x2...xn} S = { x 1 , x 2 , . . . , x n } 是一个正整数的集合,c是一个正整数。子集和问题判定是否存在 S 的一个子集 S1,使得 xS1x=c ∑ x ∈ S 1 x = c
试设计一个解子集和问题的回溯法。

对于给定的正整数的集合 S={x1x2...xn} S = { x 1 , x 2 , . . . , x n } 和正整数 c,编程计算 S 的一个子集S1,使得 xS1x=c ∑ x ∈ S 1 x = c

数据输入:
第 1 行有 2 个正整数 n 和 c,n 表示 S 的大小,c是子集和的目标值。接下来的 1 行中,有 n 个正整数,表示集合 S 中的元素。


Java

package Chapter5HuiSuFa;

import java.util.Scanner;

public class ZiJiHe {

    private static int n,c,cw,r,bestw;
    private static int[] w,x,bestx;

    public static void main(String[] args){
        Scanner input = new Scanner(System.in);

        while (true){
            cw = 0;
            r = 0;
            bestw = 0;

            n = input.nextInt();
            c = input.nextInt();

            w = new int[n+1];
            x = new int[n+1];
            bestx = new int[n+1];

            for(int i=1; i<=n; i++){
                w[i] = input.nextInt();
                r += w[i];
            }

            if(backtrack(1))
                for(int i=1; i<=n; i++){
                    if(bestx[i] == 1)
                        System.out.print(w[i]+" ");
                }
            else
                System.out.println("No Solution!");
        }
    }

    private static boolean backtrack(int i){
        if(i > n){
            for(int j=1; j<=n; j++)
                bestx[j] = x[j];
            bestw = cw;
            if(bestw == c)
                return true;
            else
                return false;
        }

        r -= w[i];
        if(cw+w[i] <= c){
            x[i] = 1;
            cw += w[i];
            if(backtrack(i+1))
                return true;
            cw -= w[i];
        }
        if(cw+r > bestw){
            x[i] = 0;
            if(backtrack(i+1))
                return true;
        }
        r += w[i];
        return false;
    }
}

Input & Output

5 10
2 2 6 5 4
2 2 6 

Reference

王晓东《计算机算法设计与分析》(第3版)P179

你可能感兴趣的:(Algorithm,Java,计算机算法设计与分析,回溯法,计算机算法设计与分析)