ACdream 1726

原题链接:

http://acdream.info/problem?pid=1726

题目大意:

输入一个n和H。接着给你n个数。问能不能取其中的一个或多个的数,使得它(们)的和为H

思路:

每个数都可以选择或者不选择,所以要分别做深搜。可以考虑开辟一个数组来存放前N项和(建议先排序)用于剪枝用途防止超时。用long long 来存放数据。防止数据过大int 或 long 存不下

代码如下:

#include 
#include 
#include 

using namespace std;

long long Number[50]; //存放N个数
long long Check[50];  //存放前N项和
long long Sum;
int InputNumber;
bool Can;


void dfs( long long tmp_sum, int Next_Loc )
{

    if( tmp_sum == Sum ) //判断返回条件
    {
        Can = true;
        return ;
    }

    if( Can || Next_Loc > InputNumber)
        return ;
    if( tmp_sum > Sum || tmp_sum + Check[InputNumber] - Check[Next_Loc - 1] < Sum ) 
        return;
        //两个途径(选或不选)开始深搜
    dfs( tmp_sum + Number[Next_Loc], Next_Loc + 1 );
    dfs( tmp_sum ,Next_Loc + 1);

}
int main()
{
    while( ~scanf("%d %lld",&InputNumber,&Sum))
    {
        int i;
        memset( Check,0,sizeof(Check));
        for( i = 1; i <= InputNumber; i++ )
        {
            scanf("%lld",&Number[i]);
            //统计前N项和
            Check[i] = Check[ i-1 ] + Number[i];
        }

        dfs( 0,1 );

        if( Can )
            cout<<"Yes"<else 
            cout<<"No"<return 0;
}

你可能感兴趣的:(dfs,搜索)