宠物小精灵之收服
题解:设状态 \(dp[i][j][k]\) 表示从前 \(i\) 个物品中选择,物品的费用 \(1\) 为 \(j\),费用 \(2\) 为 \(k\) 的最大选择数量。
则状态转移方程为:
\[dp[i][j][k] = max(dp[i - 1][j][k], dp[i - 1][j - v_1[i]][k - v_2[i]] + 1) \]跟普通01背包一样,第一维可以直接优化掉。
第一问的答案显然为 \(dp[n][m - 1]\) (注意本题中体力不能为0),第二问的答案枚举满足 \(dp[n][i] = dp[n][m - 1]\) 的最大的 \(m - i\) 即为答案。
AC代码:
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 1010;
int dp[N][N];
int v[N], w[N];
void solve() {
int n, m, k;
cin >> n >> m >> k;
for (int i = 1; i <= k; i ++) {
cin >> v[i] >> w[i];
}
for (int i = 1; i <= k; i ++) {
for (int j = n; j >= v[i]; j --) {
for (int t = m - 1; t >= w[i]; t --) {
dp[j][t] = max(dp[j][t], dp[j - v[i]][t - w[i]] + 1);
}
}
}
int res = 1e9;
for (int i = 0; i < m; i ++) {
if(dp[n][i] == dp[n][m - 1]) {
res = min(res, i);
break;
}
}
cout << dp[n][m - 1] << " " << m - res << endl;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
solve();
}
标签:费用,背包,int,res,二维,include,dp
From: https://www.cnblogs.com/Ray0430/p/18332398