AcWing 11. 背包问题求方案数(01背包计数)

简介: 笔记

背包问题求方案数


题意

有 N 件物品和一个容量是 V 的背包。每件物品只能使用一次。


第 i 件物品的体积是 vi,价值是 wi。


求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。


输出 最优选法的方案数。注意答案可能很大,请输出答案模 109+7 的结果。


思路

问题背景时 01背包问题 所以求价值的最大值可以直接用 01背包的思路求解:19.png


代码

#include <bits/stdc++.h>
//#define int long long
#define INF 0x3f3f3f3f
#define mod 1000000007
#define endl '\n'
#define rep(i, st, ed) for (int (i) = (st); (i) <= (ed);++(i))
#define pre(i, ed, st) for (int (i) = (ed); i >= (st);--(i))
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
inline int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
inline int lowbit(int x) { return x & -x; }
const int N = 1200;
int n, m;
int w[N], v[N];
int f[N];
int g[N]; // 价值为f[i] 的方案数 
void solve() {
  cin >> n >> m;
  for (int i = 1; i <= n; ++i)cin >> w[i] >> v[i];
  // 价值为f[0] 即价值为0时的方案数为 1 那就是都不选 
  g[0] = 1;
  // 01背包
  for (int i = 1; i <= n; ++i) {
    for (int j = m; j >= w[i]; --j) {
      int maxn = max(f[j], f[j - w[i]] + v[i]);
      int cnt = 0;
      if (maxn == f[j])cnt += g[j];
      if (maxn == f[j - w[i]] + v[i])cnt += g[j - w[i]];
      f[j] = maxn;
      g[j] = cnt % mod;
    }
  }
  // 求出价值最大为多少
  int cnt = 0;
  for (int i = 0; i <= m; ++i) {
    cnt = max(cnt, f[i]);
  }
  //枚举体积 如果当前体积下价值与最大价值相等  那么答案加上 g[j]
  int res = 0;
  for (int i = 0; i <= m; ++i) {
    if (f[i] == cnt)
      res = (res + g[i]) % mod;
  }
  cout << res << endl;
}
signed main() {
  // int t;cin >> t;
  // while(t--)
  solve();
  return 0;
}


目录
相关文章
|
6月前
|
算法 测试技术 C++
【数位dp】【动态规划】C++算法:233.数字 1 的个数
【数位dp】【动态规划】C++算法:233.数字 1 的个数
|
6月前
windy数(数位dp)
windy数(数位dp)
32 0
|
6月前
【每日一题Day297】LC1444切披萨的方案数 | 动态规划+二维前缀和
【每日一题Day297】LC1444切披萨的方案数 | 动态规划+二维前缀和
65 0
|
5月前
|
存储
【洛谷 P1255】数楼梯 题解(递归+记忆化搜索+高精度)
这是一个使用动态规划解决的“数楼梯”问题。给定楼梯数`N`,求不同上楼方式的数量。程序通过递归函数`f()`计算,其中`f(x) = f(x - 1) + f(x - 2)`,初始条件`f(1) = 1`,`f(2) = 2`。考虑到数据规模可能很大,使用了高精度加法运算。样例输入`4`,输出`5`。代码中定义了一个存储中间结果的向量`mem`,并提供了一个用于显示高精度数的`printv()`函数。
97 0
|
3月前
|
算法 Java
LeetCode初级算法题:子数组最大平均数+二叉树的最小深度+最长连续递增序列+柠檬水找零
LeetCode初级算法题:子数组最大平均数+二叉树的最小深度+最长连续递增序列+柠檬水找零
43 0
|
6月前
|
算法 测试技术 C#
【动态规划】【 数位dp】2827. 范围中美丽整数的数目
【动态规划】【 数位dp】2827. 范围中美丽整数的数目
|
6月前
|
算法 测试技术 C#
【数位dp】【数论】【动态规划】2999. 统计强大整数的数目
【数位dp】【数论】【动态规划】2999. 统计强大整数的数目
|
人工智能 算法 决策智能
动态规划之背包问题(01背包问题、完全背包问题、方案数填满型背包问题)
动态规划之背包问题(01背包问题、完全背包问题、方案数填满型背包问题)
252 1
|
人工智能 算法 Windows
背包问题求方案数(二)
AcWing算法提高课内容,本文讲解 动态规划
204 0
背包问题求方案数(二)