题解:
读错题以为每个物体无限量。发现每个物品只有一个后就好处理了。
解法
1
1
1:
开一个
3600
3600
3600的
b
i
t
s
e
t
bitset
bitset偷懒
想了一天才想明白这个位移,往左移
x
x
x代表在原来存在的数基础上,加上
x
x
x。
如
b
i
t
s
e
t
<
6
>
b
(
s
t
r
i
n
g
"
000001
"
)
bitset<6>b(string"000001")
bitset<6>b(string"000001")代表此时
b
[
0
]
=
t
r
u
e
b[0]=true
b[0]=true,那么
b
=
(
b
∣
b
<
<
1
)
b=(b|b<<1)
b=(b∣b<<1)代表将仅存在的
0
0
0加上1,得到
b
[
1
]
=
t
r
u
e
b[1]=true
b[1]=true,那么就得到了加上的一部分的值。
又因为可能一部分的数向左移后会溢出而导致这部分产生了贡献但却没被记录下来,所以有向右移,
众所周知向左移
x
x
x后对
m
o
d
mod
mod取模得到的结果和向右移
m
o
d
−
x
mod-x
mod−x后对
m
o
d
mod
mod取模的答案一样,所以也要记录下向右移动
m
o
d
−
x
mod-x
mod−x的贡献。
代码:
#include<cstdio>
#include<bitset>
using namespace std;
const int N = 3600;
bitset<N> b;
int main()
{
int T = 1; scanf("%d", &T);
while(T--) {
b >>= N;
int n; scanf("%d", &n);
for(int i = 0; i < n; i++) {
int x; scanf("%d", &x);
x %= N;
b |= ((b << x) | (b >> (N - x)));
b[x] = true;
}
if(b[0]) puts("YES");
else puts("NO");
}
return 0;
}