雫露露的背包
原题链接:https://ac.nowcoder.com/acm/contest/83910/G
这道题除了DFS也可以用dp。
状态转移方程为:dp[ i ][ j ] = dp[ i ][ j ] + dp[ i - 1 ][ j - t ] * space[ i ][ t ]
dp[ i ][ j ]表示到第 i 个朋友为止,取到总重量为 j 的取法组合数。space [ i ][ t ]表示第 i 个朋友手里重量为 t 的礼物的数量。
#include <bits/stdc++.h>
using namespace std;
const int N = 3010, W = 3010;
int n, w;
int space[N][W]; // 第i个朋友重量为j的礼物数量
int dp[N][W]; // 取到第i个朋友为止,拥有j重量的礼物的取法数量
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n >> w;
for(int i = 1; i <= n; i ++ ) {
int a; cin >> a;
for(int j = 1; j <= a; j ++ ) {
int b; cin >> b;
space[i][b] ++;
}
}// 完成输入
for(int j = 1; j <= W; j ++ ) {
dp[1][j] = space[1][j];
} // dp初始化
for(int i = 2; i <= n; i ++ ) {
for(int j = 1; j <= w; j ++ ) {
for(int t = 1; t <= w; t ++) {// 从第i个朋友这里取走了t重量的礼物
dp[i][j] = dp[i][j] + dp[i - 1][j - t] * space[i][t];
}
}
}
cout << dp[n][w] << endl;
}