dp 求物品组合情况

给你一堆物品,每个物品只能用一次,求物品能组合的所有情况
传送门
用01背包,初始化dp[0] = 1
然后01背包或取操作即可,时间复杂度\(O(mn)\)

int a[N], dp[N];
void solve(int kase){
    int n = read(), sum = 0;
    for(int i = 1; i <= n; i++) a[i] = read(), sum += a[i];
    dp[0] = 1;
    for(int i = 1; i <= n; i++) { // 求出放一边的情况
        for(int j = sum; j >= a[i]; j--) {
            dp[j] |= dp[j - a[i]];
        }
    }
    for(int i = 1; i <= n; i++) { // 两边都可以放的情况
        for(int j = 1; j <= sum - a[i]; j++) {
            dp[j] |= dp[j + a[i]];
        }
    }
    int k = read();
    for(int i = 1; i <= k; i++) {
        int x = read();
        printf("%s\n", x <= sum && dp[x] ? "YES" : "NO");
    }
}
posted @ 2021-04-19 11:10  Emcikem  阅读(44)  评论(0编辑  收藏  举报