原題鏈接:
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;
}