• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
不会投篮的邢
投篮三不沾
博客园    首页    新随笔    联系   管理    订阅  订阅

7-16 子集和问题

设集合S={x1,x2,…,xn}是一个正整数集合,c是一个正整数,子集和问题判定是否存在S的一个子集S1,使S1中的元素之和为c。试设计一个解子集和问题的回溯法。

输入格式:

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

输出格式:

输出子集和问题的解,以空格分隔,最后一个输出的后面有空格。当问题无解时,输出“No Solution!”。

输入样例:

在这里给出一组输入。例如:

5 10
2 2 6 5 4

输出样例:

在这里给出相应的输出。例如:

2 2 6 



思路:本题采用回溯法来实现查找满足条件的子集和, 因为是只输出一个结果所以在找到满足一个条件之后就退出查找。

import java.util.Scanner;

public class Main {
public static int n;
public static int m;
public static int a[];
public static int ans[];
public static int count=0;

public static void main(String[] args) {
Scanner in = new Scanner(System.in);
  //the length of s
  n = in.nextInt();
  //the size of target
  m = in.nextInt();
  a = new int[n];
  ans = new int[n];
  for(int i=0;i<n;i++){
    a[i] = in.nextInt();
  }
  dfs(0, 0, Rm());
  if(count==0){
    System.out.println("No Solution!");
  }
}
public static int Rm(){
  int rm=0;
  for(int i=0;i<n;i++){
  rm+=a[i];
}
return rm;
}
public static void dfs(int i, int sum, int rm){
  if(i>=n){
  if(sum==m&&count==0){
      for(int k=0;k<n;k++){
        if(ans[k]==1){
          System.out.print(a[k]+" ");
  }
}
    count++;
    System.exit(0);//找到一个结果之后强制退出,否则在pta提交会出现一个测试点超时
}
}else{
  if(sum+a[i]<=m){
    ans[i] = 1;
    dfs(i+1,sum+a[i],rm-a[i]);
  }
  if(sum+rm-a[i]>=m){
    ans[i] = 0;
    dfs(i+1, sum, rm-a[i]);
}
}
}
}

posted @ 2019-12-05 20:47  不会投篮的邢  阅读(698)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3