zoukankan      html  css  js  c++  java
  • 【9502】子集问题

    Time Limit: 10 second
    Memory Limit: 2 MB

    问题描述
    子集和问题的一个实例为〈S,C 〉。其中,S={ X1 ,X2 ,…,Xn } 是一个正整数的集合,C是一个正整数。
    编程任务 :对于给定的正整数的集合S={ X1 ,X2 ,…,Xn } 和正整数C,编程计算S 的一个子集S1 ,使得∑X (X∈S1) = C(子集s1的和等于c)

    Input

    第一行有2个正整数n和c,n表示s集合中元素的个数,c是子集和的目标值。第二行有n个正整数,表示集合s中的元素

    Output

    输出一行数据,是子集和问题的解,当问题无解时,输出"No Solution!".(有解时,在解的后面多添加一个空格和一个换行符)

    Sample Input

    5 10
    2 2 6 5 4
    

    Sample Output

    2 2 6
    
     

    【题解】

    用一个sum来累加当前选择的数。深搜下就可以了。用过的数不能再用,sum > c后剪枝。还有一个剪枝就是所有的数加起来仍然<c,这种时候直接输出无解信息就可以了。

    【代码】

    #include <cstdio>
    #include <stdlib.h>
    
    int n,c,a[5000],sum = 0,num = 0,ans[5001];
    bool bo[5001];
    
    void input_data()
    {
        scanf("%d %d",&n,&c); //输入n 和 c
        for (int i = 1;i <= n;i++)
            scanf("%d",&a[i]),sum+=a[i]; //累加a[i]的和
        if (sum < c) //如果所有数之和仍小于c则输出无解信息。
            {
                printf("No Solution!");
                exit(0);
            }
        if (sum == c) //如果所有的数刚好等于答案 则直接输出所有的数
            {
                for (int i = 1;i <= n;i++)
                    printf("%d ",a[i]);
                exit(0);
            }
        sum = 0; //这里的sum用于搜索时候的累加
        for (int i = 1;i <= 5000;i++) //所有的数一开始都可以用
            bo[i] = true;
    }
    
    void output_ans()
    {
        for (int i = 1;i <= num;i++) //输出答案
            printf("%d ",ans[i]);
    }
    
    void sear_ch(int t,int m) //t表示这个数的数值,m是这个数的下标
    {
        bo[m] = false; //标记这个数已经使用过
        sum += t; //累加当前选择的数字
        ans[++num] = t; //记录答案。
        if (sum == c) //如果累加和符合要求则输出答案。
            {
                output_ans();
                exit(0);
            }
        if (sum < c) //如果sum小于c则继续搜素,否则不搜索了 返回上一层
            for (int i = 1;i <= n;i++)
                if (bo[i]) //如果这个数字未被使用
                    sear_ch(a[i],i);
        sum -= t; //回溯
        num--;
        bo[m] =true;
    }
    
    void get_ans()
    {
        for (int i = 1;i <= n;i++)
            sear_ch(a[i],i);
        printf("No Solution!"); //最后还要再输出一次无解信息。
    }
    
    int main()
    {
        input_data();
        get_ans();
        return 0;
    }
    


     

  • 相关阅读:
    day09 文件操作
    深信服二面
    test1
    视频测试
    通过独立按键控制LED灯
    第一个LED灯
    为什么我的递归调用次数和书上的不一样?
    函数指针数组
    虚拟内存
    单元测试
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7632442.html
Copyright © 2011-2022 走看看