子集和问题

子集和问题
Time Limit: 1000 ms Memory Limit: 65536 KiB

Problem Description
子集和问题的一个实例为〈S,t〉。其中,S={ x1 , x2 ,…,xn }是一个正整数的集合,c是一个正整数。子集和问题判定是否存在S的一个子集S1,使得:

试设计一个解子集和问题的回溯法。
对于给定的正整数的集合S={ x1 , x2 ,…,xn }和正整数c,计算S 的一个子集S1,使得:

Input
输入数据的第1 行有2 个正整数n 和c(n≤10000,c≤10000000),n 表示S 的大小,c是子集和的目标值。接下来的1 行中,有n个正整数,表示集合S中的元素。
Output
将子集和问题的解输出。当问题无解时,输出“No Solution!”。

Sample Input

5 10
2 2 6 5 4

Sample Output
2 2 6

帮助自己理解,跑一边例题,可能我太笨啦,个人理解,不确定对哈
输入之后,进行sum是否小于C的判读。flag = 0,接下来dfs(0),进入dfs函数
dfs(0):if循环,v[0] = 0且c - a[0] >= 0;c = c - a[i] = 10 - 2 = 8;
v[0]被标记,ans[0] = 2存入。
else dfs(1),类似,c = 8 - 2 = 6;v[1]标记,ans[1] = 2记录下来,
继续else dfs(3),c = 6 - 6 = 0;v[2]标记,ans[2] = 6记录,c == 0满足,
有因为flag = 0,直接输出print(2);flag = 0,return;结束。
介于此处并没有体现出回溯这一步,那我们就换个例子,2 2 9 6 5,再来一次
2 2 一样,直接到9,c = 6 - 9 < 0,进不去循环,还是例子不对,2 2 5 6 2试试,c = 6 - 5 = 1,下一步dfs(3),c - 6 和c - 2都小于0,所以,回到dfs(2)......后续更新哈哈,先不想了

接下来看代码

#include
#include
#include
#include

using namespace std;

int a[10000];///输入数组
int v[10000];///标记访问
int ans[10000];///ans是记录数组
int c, n, flag;

void print(int x)
{
    for(int i = 0; i <= x; i++)
        cout<<ans[i]<<" ";
    cout<<endl;
    return;
}

void dfs(int x)
{
    if(flag == 1) return;///只需要输出一组,加以判断
    for(int i = 0; i < n; i++)
    {
        if(v[i] == 0 && c - a[i] >= 0)
        {
            if(flag == 1) return;
            c -= a[i];///用c减去每个数,其实就是几个数之和等于c
            v[i] = 1;
            ans[x] = a[i];///ans是记录数组
            if(c == 0)///如果找到一组解,直接输出,完成任务
            {
                if(flag == 0)
                    print(x);
                flag = 1;
                return;
            }
            else
                dfs(x + 1);
            if(flag == 1) return;
            v[i] = 0;///回溯一步
            c += a[i];
        }
    }
}

int main()
{
    while(cin>>n>>c)
    {
        int sum = 0;
        for(int i = 0; i < n; i++)
        {
            cin>>a[i];
            sum += a[i];
        }
        if(sum < c)///如果所有的数加起来都小于c,那么不可能有解
        {
            cout<<"No Solution!"<<endl;
            break;
        }
        memset(v, 0, sizeof(v));
        memset(ans, 0, sizeof(ans));
        flag = 0;
        dfs(0);
        if(flag == 0)
            cout<<"No Solution!"<<endl;
    }
}

你可能感兴趣的:(算法设计-搜索算法)