子集和问题

描述

子集和问题的一个实例为 (S,C)。其中,S=x1​ , x2​ , … , xn​ 是一个正整数的集合,C 是一个正整数。

对于给定的正整数的集合 S,是否存在 S 的一个子集 S1​,使得 x∈S1​∑​x=C

请设计一个求解子集和问题的回溯算法代码。

输入描述

第一行有两个正整数 n 和 C,n 表示 S 的元素个数 (0<n<7000),C 是子集和的目标值。

接下来一行是 n 个正整数,表示集合 S 中的元素。

输出描述

本题可能有多解,输出任意一个即可。子集每个元素后跟一个空格作为分隔。

例:当存在两个解 {2, 2, 6} 和 {6, 4},任意一个均可。当问题无解时,输出 No Solution!

用例输入 1 

5 10
2 2 6 5 4

用例输出 1 

2 2 6 
#include <iostream> 
#include<algorithm>
using namespace std;  

#define NUM 7010
  
int vis[NUM];  // 定义一个数组来标记元素是否被选择进入子集 
int a[NUM];  // 存储正整数集合S  
int n, C;  

int flag = 0;  // 标记是否找到解  
int sum = 0; // 当前子集的和  
  
void dfs(int k){       
    if(flag){  
        return;  
    }  
    // 如果当前子集的和等于目标值C,则输出解并设置flag为1  
    if(sum == C){  
        flag=1;  
        for(int i=1;i<=n;i++){   
            if(vis[i]){  
                printf("%d ",a[i]);  
            }  
        }  
        printf("\n");   
    }  
    if(k>n){  
        return;  
    }  
    if(sum+a[k]>C){  
        return;  
    }  
    vis[k]=1;  // 将第k个元素加入子集  
    sum=sum+a[k];    
    dfs(k+1);   
    vis[k]=0;  
    sum=sum-a[k];  
    dfs(k+1);
}  
  
int main(){  
    scanf("%d %d",&n,&C);
    int t=0;  
    for (int i=1; i<=n;i++){  
        scanf("%d",&a[i]) ; 
        t=t+a[i]; 
    }   
    if (t<C){  
        printf("No Solution!\n");  
    }else{   
        sort(a+1,a+n+1);  //排序
        dfs(1); // 从第1个元素开始搜索  
        // 如果没有找到解 
        if (!flag){  
            printf("No Solution!\n");  
        }  
    }  
    return 0;  
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值