题解 | 神奇的口袋
#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,我们认为没有物品可选,也是一种方案,第一个解法是优化版本,如果看不懂,直接看第二个即可