最开始这题我是想4条边分开看..找到一种方法填满第一条边,再填第二条....直道第四条添满..则说明找到一组解....但是WA了..不知道为什么不行..感觉上相互是没有联系的..但Discuss里的不少数据确实证明这种方法是不可行的...
然后就是搜索罗...因为长的线段显然对结果影响更大..所以将线段从大到小排序...开始我的搜索是让每个线段往4条边上分别尝试着放..直道所有线段放好..结果TLE..\
后来再一想..若DFS放满一条边后再DFS来放第二条边..这样自然就大大减少了没意义的尝试...同时若后面的边做不下去了..也能回朔回来(最初的方法就是没这个..)...这样的话就能AC了..250ms.....
Program:
#include<iostream>
#include<string.h>
#include<stdio.h>
#include<algorithm>
#include<math.h>
#include<queue>
using namespace std;
int t,n,data,a[25],have[4];
bool used[25];
bool DFS(int k,int p)
{
int i;
if (p==4) return true;
for (i=k;i<=n;i++)
if (!used[i] && data-have[p]>=a[i])
{
have[p]+=a[i];
used[i]=true;
if (have[p]==data)
{
if (DFS(1,p+1)) return true;
}else if (DFS(i+1,p)) return true;
used[i]=false;
have[p]-=a[i];
}
return false;
}
bool getanswer()
{
int i;
if (data%4) return false;
data/=4;
memset(have,0,sizeof(have));
memset(used,false,sizeof(used));
return DFS(1,0);
}
bool cmp(int a,int b)
{
return a>b;
}
int main()
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
scanf("%d",&t);
while (t--)
{
int i;
scanf("%d",&n);
data=0;
for (i=1;i<=n;i++)
{
scanf("%d",&a[i]);
data+=a[i];
}
sort(a+1,a+1+n,cmp);
if (getanswer()) printf("yes\n"); else printf("no\n");
}
return 0;
}