原题链接:
http://acdream.info/problem?pid=1726
题目大意:
输入一个n和H。接着给你n个数。问能不能取其中的一个或多个的数,使得它(们)的和为H
思路:
每个数都可以选择或者不选择,所以要分别做深搜。可以考虑开辟一个数组来存放前N项和(建议先排序)用于剪枝用途防止超时。用long long 来存放数据。防止数据过大int 或 long 存不下
代码如下:
#include <iostream>
#include <cstdio>
#include <algorithm>
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"<<endl;
else
cout<<"No"<<endl;
}
return 0;
}