1 条题解
-
0
#include <bits/stdc++.h> using namespace std; // [1] m-目标和;n-输入的正整数个数 int m,n; // [2] arr数组-存储输入的N个正整数(下标1~n) int arr[2100]; // [3] dp数组-动态规划状态,dp[j]表示子集和为j的方案数,用long long防止方案数过大溢出int long long dp[11000]={}; int main() { // 问题分析:01背包计数问题,每个元素只能选一次,求子集和为M的方案数(相同值不同位置算不同方案) // 解题步骤:1.初始化dp[0]=1(空集是和为0的唯一方案);2.逆序遍历每个元素,更新dp[j] += dp[j-arr[i]](选当前元素的方案数=前j-arr[i]的方案数); // 3.最终dp[m]即为和为M的方案数 cin>>n>>m; // [4] 读取元素个数n和目标和m for(int i=1;i<=n;i++) cin>>arr[i]; // [5] 读取N个正整数,存入arr数组 dp[0]=1; // [6] 初始化:和为0的方案数为1(选择空集) // 01背包核心循环:遍历每个元素,逆序更新方案数 for(int i=1;i<=n;i++){ // [7] 外层循环:遍历每个元素(每个元素仅能选一次) // 内层循环:逆序遍历目标和(避免重复选择同一元素,保证每个元素仅被计算一次) for(int j=m;j>=arr[i];j--){ // [8] 状态转移:不选当前元素时dp[j]不变;选当前元素时,方案数增加dp[j-arr[i]](前j-arr[i]的方案数) dp[j] = dp[j] + dp[j-arr[i]]; } } cout<<dp[m]; // [9] 输出子集和为m的方案数 return 0; }
- 1
信息
- ID
- 1355
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者