小 A 的卡牌游戏(dp, 贪心)

2 篇文章 0 订阅
1 篇文章 0 订阅

传送门: 小 A 的卡牌游戏 - Gym 103186B - Virtual Judge

小 A 最近沉迷于一款名为 Hearthverse 的卡牌游戏。在这款游戏中,卡被分为了三个种类(随从、法术和魔法阵),在组卡时,这款游戏严格规定了卡组中每种卡牌的数量,具体来说,一副 nn 张卡的卡组需要包含恰好 aa 张随从卡, bb 张法术卡和 cc 张魔法阵卡,并且 a + b + c = na+b+c=n。

在游戏中,有一个叫做 "3pick" 的组卡竞技方式,游戏会给出 nn 次三选一的机会,三张卡分别来自三个种类。每次玩家需要从三张卡中选出一张卡加入自己的卡组。为了使卡组强度尽量高,小 A 给每张卡设定了一个强度值,而卡组的强度就是所有卡强度值的和,他希望他最后组出的卡组的强度可以尽量高。

Input

第一行有四个整数 n, a, b, cn,a,b,c (1\leq a, b, c\leq n \leq 5000, a+ b + c = n1≤a,b,c≤n≤5000,a+b+c=n),分别表示卡组的总卡数与每种种类的卡的张数要求。

接下来 nn 行,每行代表一次 "3pick" 的机会,第 ii 行有三个整数 a_i,b_i,c_iai​,bi​,ci​ (1 \leq a_i,b_i,c_i \leq 10^91≤ai​,bi​,ci​≤109) 分别表示这一次选择中随从卡、法术卡和魔法阵卡的强度值。

Output

在一行输出一个整数,表示 小 A 能组出的卡组的最大强度值。

Examples

Input

3 1 1 1
4 1 6
1 1 10
5 7 4

Output

21

Input

6 3 2 1
1000000000 1 1
1000000000 1 1
1000000000 1 1
1 1000000000 1
1 1000000000 1
1 1 1000000000

Output

6000000000

训练赛时傻傻的写了一个tle的代码,当发现开不了三维数组想到了降维,但以为用map代替可以过服气,想想当时傻傻的用直接搜。当然这也挺好的,也学会了另外一种降维方式,那么总结下现在接触到的降维方式1,当只有两个数,选一个就不选另一个那种就可以只计算其中一个。2就是这里的贪心降维。相同点就是两个方式都是第一维记录的是总数,第二维记录的是某个数的值。

        当时训练赛时我也想过降维的,当是怎么说降维时想不到a, b怎么处理,开了题解之后才发现能够用贪心处理。确实当只有a和b时,只要a与b的差值越大那我们我们会优先选择大的那个数。

代码:

#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;

#define ll long long

const int N = 5010;

ll dp[N][N];

struct Node {
	int a, b, c;
}node[N];

bool cmp(Node &a, Node &b) {
	return a.a - a.b > b.a - b.b;
}

int main() {
	int n, a, b, c;
	cin >> n >> a >> b >> c;

	for (int i = 1; i <= n; i++) cin >> node[i].a >> node[i].b >> node[i].c;

	sort(node + 1, node + n + 1, cmp);

	for (int i = 1; i <= n; i++) {
		for (int j = 0; j <= i; j++) {
			if (j) dp[i][j] = dp[i - 1][j - 1] + node[i].c;
			if (j == i) continue;

			if (i - j <= a) dp[i][j] = max(dp[i][j], dp[i - 1][j] + node[i].a);
			else dp[i][j] = max(dp[i][j], dp[i - 1][j] + node[i].b);
		}
	}

	cout << dp[n][c];
	return 0;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值