思路是如果边长可能为这个值,就进行判定。一组数据一共是需要四次判定,判定的时候,就相当于是从前m个物品中没有被选过的物品中,看看能不能凑成平均值。但是这样只有50分,而且一个很玄学的事情就是把N换成50就只有40
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 26;
int n,m;
int a[N];
bool st[N];
bool f[5050];
bool find(int avg)
{
memset(f,0,sizeof f);
f[0] = true;
for (int i = 1; i <= m; i ++ )
{
//cout << a[i] << endl;
if(st[i]) continue;
for(int j = avg; j >= a[i]; j --)
{
f[j] |= f[j-a[i]];
//cout << j << " " << f[j] << endl;
}
}
if(!f[avg]) return false;
int j = avg;
for(int i = m; i >= 1; i --)
{
if(!st[i] && f[j] == f[j-a[i]])
{
st[i] = true;
j -= a[i];
}
}
return true;
}
bool check(int avg)
{
memset(st, 0, sizeof st);
for(int i = 1;i <= 4; i ++)
{
if(!find(avg)) return false;
}
return true;
}
int main()
{
cin >> n;
while (n -- )
{
cin >> m;
int sum = 0,maxlen = 0;
for (int i = 1; i <= m; i ++ )
{
cin >> a[i];
sum += a[i];
maxlen = max(maxlen,a[i]);
}
if(sum % 4 != 0)
{
puts("no");
continue;
}
else
{
int avg = sum / 4;
if(maxlen > avg) puts("no");
else if(check(avg)) puts("yes");
else puts("no");
}
}
return 0;
}