![](https://img-blog.csdnimg.cn/img_convert/d4374bdf5902ece4a3957799503fc112.png)
一.题目分析
假如现在我有n个精灵球,皮卡丘的体力为m,有k种小精灵,从前i(i<=k)个精灵中选择精灵收服,且收服所用的精灵球为j1(j1<=n),所消耗的体力j2(j2<=m)。
二.集合表示
我们用f[i,j1,j2]表示从前i(i<=k)个精灵中选择精灵收服,且收服所用的精灵球为j1(j1<=n),所消耗的体力j2(j2<=m)。
三.计算集合
收服第i个小精灵或者不收服
f[i,j1,j2]=max(f[i-1,j1,j2],f[i-1,j1-v1[i],j2-v2[i]+1]
代码如下:
#include <iostream>
using namespace std;
const int N = 1010, M = 510, K = 110;
int n, m, k;
int f[N][M];
int v1[K], v2[K];
int main(){
cin >> n >> m >> k;
for (int i = 1; i <= k; i ++ )
cin >> v1[i] >> v2[i];
for (int i = 1; i <= k; i ++)
for (int j1 = n; j1 >= v1[i]; j1 -- )
for (int j2 = m; j2 >= v2[i]; j2 -- )
f[j1][j2] = max(f[j1][j2], f[j1 - v1[i]][j2 - v2[i]] + 1);
int res = -1, t;
for (int i = 0; i <= m - 1; i ++ )
if (res < f[n][i]){
res = f[n][i];
t = i;
}
cout << res << ' ' << m - t << endl;
return 0;
}