Description

给一个天平和一堆已知重量的石头,判断目标重量能否搭配出来。

Solution

假设石头放左边贡献是 , 放右边是
根据数据,最大的重量只能是
不妨令 为使用第 个石头的时候能否到达重量为 的状态
显然有

  • 不取
  • 放在右边
  • 放在左边

最后查询的时候检查是否能到达状态即可
时间复杂度

Code

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 5e5 + 5;
int a[105];
bool vis[10505];
bool dp[105][10505];
int main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int n; 
    while(cin >> n) {
        memset(dp, false, sizeof(dp));
        memset(vis, false, sizeof(vis));
        for(int i = 1; i <= n; i++) {
            cin >> a[i];
        }    
        dp[0][0] = true;
        for(int i = 1; i <= n; i++) {
            for(int j = 0; j <= 1e4; j++) {
                dp[i][j] |= dp[i - 1][j];
                dp[i][j] |= dp[i - 1][abs(j - a[i])];
                dp[i][j] |= dp[i - 1][j + a[i]];
                if(dp[i][j]) {
                    vis[j] = true;
                }
            }
        }
        int m; cin >> m;
        while(m--) {
            int x; cin >> x;
            if(x > 1e4) {
                cout << "NO\n";
            } else {
                if(vis[x]) {
                    cout << "YES\n";
                } else {
                    cout << "NO\n";
                }
            }
        }
    }
    return 0;
}