DFS + 剪枝
一定要加上最长的那个边比s/4小
不然就WA
不知为何?
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int MAXM = 20 + 9;
int s, m, s4;
int a[MAXM];
bool used[MAXM];
bool flag;
void dfs(int k, int t, int ns) //搜到第k条边 t条边已经完成 当前完成ns
{
if (flag) return;
if (t == 3) {
flag = true;
return;
}
for (int i = k; i < m; i++) {
if (!used[i]) {
used[i] = true;
if (ns + a[i] == s4) {
dfs(0, t + 1, 0);
} else
{
if (ns + a[i] < s4) {
dfs(i + 1, t, ns + a[i]);
}
}
used[i] = false;
}
}
}
void solve()
{
memset(used, 0, sizeof(used));
flag = false;
s = 0;
int l = 0;
scanf("%d", &m);
for (int i = 0; i < m; i++) {
scanf("%d", &a[i]);
s += a[i];
l = max(l, a[i]);
}
s4 = s / 4;
if (s % 4 || l > s4) {
flag = false;
}
else {
dfs(0, 0, 0);
}
if (flag) {
puts("yes");
}
else {
puts("no");
}
}
int main()
{
//freopen("in.txt", "r", stdin);
int n;
scanf("%d", &n);
while (n--) {
solve();
}
}