#include <iostream> #include <cmath> #include <cstring> using namespace std; const int N = 110, M = N * N; int n; bool f[N][M]; /* 假设,物品放在左侧,重量显示在右侧 假设我们已经走了i-1个石头,且当前可以称j千克现在到了第i块石头 那我可以做的事情是什么呢? 1.我不拿这块石头f[i][j] = true; 2.我拿这块石头 2.1将这块石头放到右侧f[i][j + x] = true; 2.2将这块石头放在左侧f[i][abs(j - x)] = true; 这里利用了拓扑图出边的思路。 就是在当前节点考虑可以由当前节点到达哪些节点 */ int main() { while (cin >> n) { //初始化 memset(f, 0, sizeof f); for (int i = 0; i <= n; i ++ ) f[i][0] = true; for (int i = 1; i <= n; i ++ ) { int x; cin >> x; for (int j = 0; j <= 10000; j ++ ) { if (f[i - 1][j]) { f[i][j] = true;//不选第i个石头 f[i][j + x] = true;//将第i个石头放在右侧 f[i][abs(j - x)] = true;//讲第i个石头放在左侧 } } } int m; cin >> m; while (m -- ) { int t; cin >> t; if (t > 10000 || !f[n][t]) puts("NO"); else puts("YES"); } } return 0; }