蓝桥杯 装饰珠 动态规划, 2020, 省赛

装饰珠 动态规划, 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;
}
  • 6
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值