分组背包
分组背包其实就是通过更改和增加枚举顺序来把01背包中的状态(第i个j重量时的最大价值转化为第i组j重量时的最大价值)。
但是要注意的就是枚举顺序一定要正确。
#include <bits/stdc++.h> using namespace std; int n, m, k; int a[110][1010]; int w[100100], v[1010010], dp[101000]; int main() { scanf("%d%d", &m, &n); for (int i = 1; i <= n; i++) { int b; scanf("%d%d%d", &w[i], &v[i], &b); k = max(k, b); a[k][++a[k][0]] = i; } for (int i = 1; i <= k; i++) for (int c = m; c >= 0; c--) //这个一定要在外面 ,因为如果在里面的话,则dp[v]该状态包括i组的其他成员。但是如果在外面, 则dp[c-w[a[i][j]]]其实是上一组的dp[i-1][c-w[a[i][j]]],所以要放在外面。 for (int j = 1; j <= a[i][0]; j++) if (c - w[a[i][j]] >= 0) dp[c] = max(dp[c], dp[c - w[a[i][j]]] + v[a[i][j]]); printf("%d", dp[m]); return 0; }