题目大意
给出一个数组
a
i
a_i
ai,问是否存在一个
b
i
b_i
bi,满足:
∀
i
,
∃
j
,
k
a
i
=
b
j
−
b
k
\forall i,\exist j,k a_i=b_j-b_k
∀i,∃j,kai=bj−bk
无需求出具体的
b
i
b_i
bi,只需要判断是否可行。
时间限制
1s
数据范围
n ≤ 10 n\le 10 n≤10
题解
不妨把
b
i
b_i
bi看成点权,则
a
i
a_i
ai看作边权。
这样就可以通过暴力枚举,看看是否会重复到达同一个点,如果有,则是可以,否则不可以。
Code
//#pragma GCC optimize (2)
//#pragma G++ optimize (2)
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <iostream>
#include <vector>
#include <queue>
#include <set>
#define G getchar
#define ll long long
using namespace std;
ll read()
{
char ch;
for(ch = G();(ch < '0' || ch > '9') && ch != '-';ch = G());
ll n = 0 , w;
if (ch == '-')
{
w = -1;
ch = G();
} else w = 1;
for(;'0' <= ch && ch <= '9';ch = G())n = (n<<1)+(n<<3)+ch-48;
return n * w;
}
const int N = 50003;
const int mo = 998244353;
int n , a[N] , b[N];
bool bz[N] , ans;
set<int> q;
void dfs(int x , int s)
{
if (x > n)
{
if (q.count(s)) ans = 1;
q.insert(s);
return;
}
if (ans) return;
dfs(x + 1 , s);
dfs(x + 1 , s+ a[x]);
}
int main()
{
//freopen("b.in","r",stdin);
//freopen("2.txt","w",stdout);
for (int T = read() ; T ; T--)
{
n = read();
for (int i = 1 ; i <= n ; i++)
a[i] = read();
ans = 0;
q.clear();
dfs(1 , 0);
if (ans) puts("YES"); else puts("NO");
}
}