部分和问题——DFS

题目描述
给定整数a1、a2、…an,判断是否可以从中选出若干数,使它们的和恰好为k。
输入
有多组测试数据。每组测试数据两行:
第一行:正整数n、整数k,n表示数的个数,k表示数的和。
第二行:n个数
输出
每组测试数据,如果和恰好可以为k,输出“YES”,并按输入顺序依次输出是由哪几个数的和组成,否则“NO”
样例输入
5 20
10 2 4 7 1
4 10
1 2 -10 4
样例输出
YES
10 2 7 1
NO

采用DFS
AC代码如下:

#include <iostream>
#include <cstring>
using namespace std;
int n,k;//n是个数,k是数的和
const int maxn=1e5+5;
bool isok[maxn];
int a[maxn];
bool dfs(int x,int sum)
{
    if(x==n)
        return sum==k; //递归结束条件 当看到n个数字时候 判断sum是不是等于k
    else if(sum>k)   //剪枝 不考虑 sum>k的情况(减少搜索情况)
        return false;
    else
    {
        if(dfs(x+1,sum)) //不加下一个数
            return true;
        else if(dfs(x+1,sum+a[x+1])) //加下一个数
        {
            isok[x+1]=1;
            return true;
        }
    }
    return false;
}
int main()
{
    while(cin>>n>>k)
    {
        memset(isok,0,sizeof(isok));
        for(int i=1;i<=n;i++)
            cin>>a[i];
        if(dfs(0,0))
        {
            cout<<"YES"<<endl;
            bool tag=false;
            for(int i=1;i<=n;i++)
                if(isok[i])
                    if(tag)
                        cout<<' '<<a[i];
                    else
                    {
                        cout<<a[i];
                        tag=true;
                    }
            cout<<endl;
        }
        else cout<<"NO"<<endl;

    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43508782/article/details/85057678
今日推荐