从大到小排序可以减少耗时,
从小到大会增加耗时;
注意回溯 和 剪枝
/*
*HDU 1518
*fuqiang11
*DFS
*2013/7/28
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define maxn 20+3
int a[maxn];
bool visit[maxn];
int N,M,eva;
int cmp(int x, int y)
{
return x > y;
}
int DFS(int st,int sum, int num)
{
if(num == 4)
{
return 1;
}
for(int i = st; i <= M; i++)
{
if(!visit[i])
{
if(sum + a[i] == eva)
{
visit[i] = true;
if(DFS(1,0,num+1)) //搜索到一条边,继续搜(从起点开始搜索)
return 1;
visit[i] = false;
}
else if(sum + a[i] < eva)
{
visit[i] = true;
if(DFS(i+1,sum+a[i],num))
return 1;
visit[i] = false;
}
}
}
return 0;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in","r",stdin);
#endif
cin>>N;
while(N--)
{
cin>>M;
int sum = 0,MAX = 0;
for(int i = 1; i <= M; i++)
{
cin>>a[i];
sum += a[i];
// MAX = max(MAX,a[i]);
}
eva = sum / 4;
if(sum % 4 != 0 || M < 4)
{
puts("no");
continue;
}
memset(visit,false,sizeof(visit));
sort(a+1,a+M+1,cmp);
if(!DFS(1,0,0))
puts("no");
else
puts("yes");
}
}