题意
传送门 NC14699
题解
设获得最大 A T K ATK ATK 的配置中,从者数量为 n 1 n1 n1,装备数量为 n 2 n2 n2,则问题为满足 0 ≤ n 2 ≤ n 1 ≤ 5 0\leq n2\leq n1\leq 5 0≤n2≤n1≤5 的条件下, ∑ 从 者 a i + ∑ 装 备 a i ′ \sum_{从者} a_{i}+\sum_{装备} a_{i'} ∑从者ai+∑装备ai′ 的最大值。
如果已知选择 j j j 个从者或装备,花费不大于 k k k 时,能够获得的最大 A T K ATK ATK 值,那么枚举从者、装备的数量以及花费,跟新答案即可。
对于从者或装备而言,求
A
T
K
ATK
ATK 的最大值其实就是需要考虑选择物品数量的
01
01
01 背包问题。以从者为例,
d
p
[
i
]
[
j
]
[
k
]
dp[i][j][k]
dp[i][j][k] 代表从者
[
0
,
i
]
[0,i]
[0,i] 中选择
j
j
j 个且花费不超过
k
k
k 时能够获得的最大
A
T
K
ATK
ATK 值,则有递推式
d
p
[
i
]
[
j
]
[
k
]
=
m
a
x
(
d
p
[
i
−
1
]
[
j
]
[
k
]
,
d
p
[
i
−
1
]
[
j
−
1
]
[
k
−
b
[
i
]
]
dp[i][j][k]=max(dp[i-1][j][k], dp[i-1][j-1][k-b[i]]
dp[i][j][k]=max(dp[i−1][j][k],dp[i−1][j−1][k−b[i]] 实现上复用数组,则第二、第三维根据递推关系需要逆向遍历。
#include <bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define maxn 305
#define maxd 140
int d, n[2], used[6][maxd], a[2][maxn], b[2][maxn], dp[2][6][maxd];
int main()
{
scanf("%d%d%d", &n[0], &n[1], &d);
for (int i = 0; i <= 1; i++)
{
for (int j = 0; j < n[i]; j++)
{
scanf("%d%d", a[i] + j, b[i] + j);
}
}
for (int f = 0; f <= 1; f++)
{
for (int i = 0; i < n[f]; i++)
{
for (int j = 5; j >= 1; j--)
{
for (int k = d; k >= b[f][i]; k--)
{
dp[f][j][k] = max(dp[f][j][k], dp[f][j - 1][k - b[f][i]] + a[f][i]);
}
}
}
}
int res = 0;
for (int n1 = 0; n1 <= 5; n1++)
{
for (int c1 = 0; c1 <= d; c1++)
{
for (int n2 = 0; n2 <= n1; n2++)
{
res = max(res, dp[0][n1][c1] + dp[1][n2][d - c1]);
}
}
}
printf("%d\n", res);
return 0;
}