装饰珠 动态规划, 2020, 省赛
题目描述
在怪物猎人这一款游戏中,玩家可以通过给装备镶嵌不同的装饰珠来获取 相应的技能,以提升自己的战斗能力。
已知猎人身上一共有 6 件装备,每件装备可能有若干个装饰孔,每个装饰孔有各自的等级,可以镶嵌一颗小于等于自身等级的装饰珠 (也可以选择不镶嵌)。
装饰珠有 MM 种,编号 1 至 MM,分别对应 MM 种技能,第 ii 种装饰珠的等级为 L_iLi,只能镶嵌在等级大于等于 L_iLi 的装饰孔中。
对第 ii 种技能来说,当装备相应技能的装饰珠数量达到 K_iKi 个时,会产生 W_i(K_i)Wi(Ki) 的价值。镶嵌同类技能的数量越多,产生的价值越大,即 W_i(K_i − 1) < W_i(K_iWi(Ki−1)<Wi(Ki)。但每个技能都有上限 P_i(1 \leq P_i \leq 7)Pi(1≤Pi≤7),当装备的珠子数量超过 P_iPi 时,只会产生 W_i(P_i)Wi(Pi) 的价值。
对于给定的装备和装饰珠数据,求解如何镶嵌装饰珠,使得 6 件装备能得到的总价值达到最大。
输入描述
输入的第 1 至 6 行,包含 6 件装备的描述。其中第 ii 的第一个整数 N_iNi 表示第 ii 件装备的装饰孔数量。后面紧接着 N_iNi 个整数,分别表示该装备上每个装饰孔的等级 L\ (1 \leq L \leq 4)L (1≤L≤4)。
第 7 行包含一个正整数 MM,表示装饰珠 (技能) 种类数量。
第 8 至 MM + 7 行,每行描述一种装饰珠 (技能) 的情况。每行的前两个整数 L_j\ (1 \leq L_j \leq 4)Lj (1≤Lj≤4) 和 P_j\ (1 \leq P_i \leq 7)Pj (1≤Pi≤7) 分别表示第 jj 种装饰珠的等级和上限。接下来 P_jPj 个整数,其中第 kk 个数表示装备该中装饰珠数量为 kk 时的价值 W_j(k)Wj(k)。
其中,1 \leq N_i \leq 50, 1 \leq M \leq 10^4, 1 \leq W_j(k) \leq 10^41≤Ni≤50,1≤M≤104,1≤Wj(k)≤104。
输出描述
输出一行包含一个整数,表示能够得到的最大价值。
输入输出样例
示例
输入
1 1
2 1 2
1 1
2 2 2
1 1
1 3
3
1 5 1 2 3 5 8
2 4 2 4 8 15
3 2 5 10
输出
20
样例说明
按照如下方式镶嵌珠子得到最大价值 18,括号内表示镶嵌的装饰珠的种类编号:
1: (1)
2: (1) (2)
3: (1)
4: (2) (2)
5: (1)
6: (2)
4 颗技能 1 装饰珠,4 颗技能 2 装饰珠 W_1(4) + W_2(4) = 5 + 15 = 20。W1(4)+W2(4)=5+15=20。
运行限制
• 最大运行时间:1s
• 最大运行内存: 256M
来自 https://www.lanqiao.cn/problems/507/learning/
#include<iostream>
#include<algorithm>
using namespace std;
int Solution() {
int n, sum = 0, L[5] = { 0 }, m, M, W[5][10] = { 0 }, le, P, res = 0;
for (int i = 0; i < 6; i++) {
cin >> n;
sum += n;
for (int j = 0; j < n; j++) {
cin >> m;
L[m]++;
}
}
cin >> M;
int ww;
for (int i = 0; i < M; i++) {
cin >> le >> P;
for (int j = 1; j <= P; j++) {
cin >> ww;
if (ww > W[le][j])
W[le][j] = ww;
if ((j + 1 > P) && P < 7)
for (int k = j + 1; k <= 7; k++)
W[le][k] = W[le][k - 1];
}
}
for (int i = 0; i <= L[4]; i++) {
for (int j = 0; j <= (sum-L[1]-L[2] - i); j++) {
for (int k = 0; k <= (sum-L[1] - (i + j)); k++) {
for (int s = 0; s <= (sum - (i + j + k)); s++) {
int a, b, c, d;
if (i > 7)
a = 7;
else
a = i;
if (j > 7)
b = 7;
else
b = j;
if (k > 7)
c = 7;
else
c = k;
if (s > 7)
d = 7;
else
d = s;
res = max(res, W[4][a] + W[3][b] + W[2][c] + W[1][d]);
}
}
}
}
return res;
}
int main() {
cout << Solution();
return 0;
}