题目链接:http://acm.dlut.edu.cn/problem.php?id=1215
题目描述:给出N个整数,每个数范围在[-1000,1000],问能不能在N个数中选出一些数(但不可以不选,且每个数最多只能被选择一次),使他们的和为0
解题思路:OJ上竟然有人发邮件问我。。点开一看还是我没做过的题。。一道DFS
好吧。。去敲了一下。显然得剪枝一下才能过,懒得剪枝WA了一下,改完就过了
把数字分成正数和负数
sum大于0从负数那边找
sum小于0从正数那边找
竟然还跑了0ms。。。无语
AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int arr[50],vis[50];
int n,sum,found,mid,fu,zh;
void dfs(int i)
{
//cout<<sum<<endl;
if(found)return;
if(!sum)
found=1;
else
{
vis[i]=1;
int j;
if(sum>0)
{
for(j=fu+1;j<mid;j++)
{
if(!vis[j])
{
vis[j]=1;
sum+=arr[j];
fu++;
dfs(j);
fu--;
vis[j]=0;
sum-=arr[j];
}
}
}
else
{
for(j=zh++;j<n;j++)
{
if(!vis[j])
{
vis[j]=1;
sum+=arr[j];
dfs(j);
vis[j]=0;
sum-=arr[j];
}
}
}
}
}
int solve()
{
int i;
for(i=0;i<n;i++)
{
if(arr[i]>0)return 0;
sum=arr[i];
found=0;
fu=i;zh=mid;
memset(vis,0,sizeof(vis));
dfs(i);
if(found)
return 1;
return 0;
}
}
int main()
{
freopen("input.txt","r",stdin);
int T,i;
scanf("%d",&T);
while(T--)
{
memset(arr,0,sizeof(arr));
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d",&arr[i]);
sort(arr,arr+n);
for(i=0;i<n;i++)
{
if(arr[i]>0)
{
mid=i;break;
}
}
int ans=solve();
if(ans)
printf("Yes\n");
else
printf("No\n");
}
return 0;
}