这道题我们可以用 d f s dfs dfs 的方式来做。
可以先对 a [ 1... n ] a[1...n] a[1...n] 取 max \max max, min \min min 和 s u m sum sum。
- 若 s u m m o d 4 sum \bmod 4 summod4 不等于 0 0 0,那么直接输出 n o no no。
- 若 m x > s u m / 4 mx > sum/4 mx>sum/4 ,也输出 n o no no。
- 最后判断 d f s ( 1 , 0 , a [ 1 ] ) dfs(1,0,a[1]) dfs(1,0,a[1]) 是否为 t r u e true true 即可。
注意,每次运行前都要初始化!
代码
#include<bits/stdc++.h>
using namespace std;
int sum,mx,mn,n,a[25];
bool vis[25];
bool dfs(int x,int p,int tot){
if(tot==sum){ //基本情况
p++;
tot=0;
x=0;
}
if(mn+tot>sum) //剪枝1
return false;
if(p==3) //有三条了,最后一条肯定符合
return true;
int l=-1e9;
for(int i=x+1;i<=n;i++)
if(vis[i]==false&&a[i]!=l){
vis[i]=true;
if(dfs(i,p,tot+a[i])==true) //下一层
return true;
vis[i]=false; //回溯
l=a[i];
}
return false;
}
bool cmp(int x,int y){
return x>y;
}
int main(){
int t;
scanf("%d",&t);
while(t--){
mn=1e9;
mx=0;
sum=0;
memset(vis,false,sizeof(vis));
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
sum+=a[i]; //求和
mx=max(mx,a[i]); //求max
mn=min(mn,a[i]); //求min
}
sort(a+1,a+n+1,cmp); //把a从大到小排序
if(sum%4!=0){
printf("no\n");
continue;
}
sum/=4;
if(mx>sum){
printf("no\n");
continue;
}
vis[1]=true;
if(dfs(1,0,a[1])==true)
printf("yes\n");
else
printf("no\n");
}
return 0;
}