题解 | 神奇的口袋

#include <bits/stdc++.h>
#include <cstring>
using namespace std;

int main(){
    int n;
    while(cin>>n){
        int dp[41];
        memset(dp, 0, sizeof(dp));
        dp[0]=1;
        for(int i=0;i<n;i++){
            int a;
            cin>>a;
            for(int j =40;j>=a;j--){
                dp[j]=dp[j]+dp[j-a];
            }
        }
        cout<<dp[40]<<endl;
    }
}
#include <bits/stdc++.h>
using namespace std;

int main() {
    int n;
    while (cin >> n) {
        vector<int> nums(n);
        for (int i = 0; i < n; i++) {
            cin >> nums[i];
        }

        // 定义dp数组,dp[i][j]表示前i个物品中,总和为j的方案数
        int dp[n + 1][41];
        memset(dp, 0, sizeof(dp));
        dp[0][0] = 1; // 初始化:选0个物品,总和为0时方案数为1

        for (int i = 1; i <= n; i++) {
            for (int j = 0; j <= 40; j++) {
                // 不选第i个物品
                dp[i][j] = dp[i - 1][j];
                // 选第i个物品(保证不越界)
                if (j >= nums[i - 1]) {
                    dp[i][j] += dp[i - 1][j - nums[i - 1]];
                }
            }
        }

        cout << dp[n][40] << endl; // 输出从n个物品中选,总和为40的方案数
    }
}

01背包问题,直接写优化版本了,本质上逻辑是一样的,我们需要求组合,也就是在背包问题的逻辑下进行修正,修正为,当前背包大小下,选取物品的方案数,对于0,我们认为没有物品可选,也是一种方案,第一个解法是优化版本,如果看不懂,直接看第二个即可

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务