题面
题解(二维费用01背包)
花费1 : 精灵球数量
花费2 :皮卡丘体力值
价值 :小精灵的数量(每只精灵价值为1)
状态表示 :f [ i , j , k ] 表示所有只考虑前i个物品,且花费1不超过 j,花费2不超过k的选法的最大值
状态计算:f[ i , j , k ] = Max( f [ i - 1 , j , k ] , f [ i - 1 , j - v1 [ i ],k - v2 [ i ] ] + 1)
注意:题目说道:使得皮卡丘体力小于等于0的野生小精灵也不会被小智收服,因此皮卡丘的体力值需在V2 - 1时开始
时间复杂度 : O( K N M )
代码
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 1010;
//精灵球数量,皮卡丘初始体力
int N, M, K;
//从前i个物品中选,花费1(精灵球数量)不超过j,花费2(皮卡丘体力值)不超过k选法的最大值
int f[maxn][maxn];
int main() {
cin >> N >> M >> K;
for (int i = 1; i <= K; i++) {
int v1, v2;
cin >> v1 >> v2;
for (int j = N; j >= v1; j--) {
for (int k = M - 1; k >= v2; k--) {
f[j][k] = max(f[j][k], f[j - v1][k - v2] + 1);
}
}
}
int minn = 0; //找一个价值和f[N][M-1]一样,但消耗体力最小的
for (int i = 0; i <= M - 1; i++) {
if (f[N][M - 1] == f[N][i]) {
minn = i;
break;
}
}
cout << f[N][M - 1] << " " << M - minn << endl;
return 0;
}