这道DFS题目一看上去就有思路因为这直接排个序一路加过去就行了,但是这个题目定的实在是太好了
稍微姿势不对就会WA或者超限,而且这里考到的剪枝知识让我大开眼见
刚开始排序排反了,WA了几发,后来剪枝剪得不好又超时了几发
后来想到了一个方法,就是存一个数组,如果后面连续的的数小于rest那么就没有搜下去的必要的,直接return false
我做的那叫一个红光满面,酣畅淋漓。
来一发又臭又长的的代码
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
int sum[55];int n,m;
long long a[55];long long num;
bool cmp(long long a,long long b)
{
return a>b;
}
bool dfs(int pos,long long rest)
{
int i;
if(rest==0)
return true;
else if(rest>sum[pos])//A了觉得没事做的可以把这行和return false注销了试一试
return false;
for(i=pos;i>=0;i--)
{
if(a[i]>rest)continue;
if(rest==a[i])return true;
if(i!=0)
{
if(dfs(i-1,rest-a[i]))
return true;
}
else
{
if(rest==a[i])
return true;
return false;
}
}
return false;
}
int main()
{
int i;
while(scanf("%d%lld",&m,&num)!=EOF)
{
n=0;
memset(sum,0,sizeof(sum));
memset(a,0,sizeof(a));
long long r;
for(i=0;i<m;i++)
{
scanf("%lld",&r);
if(r>num)continue;
a[n++]=r;
}
sort(a,a+n);
for(i=0;i<n;i++)
{
if(i==0)
sum[i]=a[i];
else
sum[i]=sum[i-1]+a[i];
}
if(dfs(n-1,num))
{
printf("Yes\n");
}
else
printf("No\n");
}
return 0;
}