小 A 的卡牌游戏(Gym - 103186B)

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

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

Input

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

接下来n行,每行代表一次"3pick"的机会,第i行有三个整数a,b,C,(1 < a,b,C < 109)分别表示这一次选择中随从卡、法术卡和魔法阵卡的强度值。

Output

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

Sample 1

Inputcopy

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

Outputcopy

21

Sample 2

Inputcopy

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

Outputcopy

6000000000

题解

在这里插入图片描述

假如就只有A和B,种类要求 1 1 ,按照b-a递减排序

BA
400300
10097
那么它的最优就是400+97

A和B 要求 2 3

BA
400300
10097
9996
42
100100
那么它的最优就是400+100+96+2+100 或 400+99+97+2+100 因为第二行和第四行都是 b-a=3 谁在前谁在后答案都一样

代码1

#include "bits/stdc++.h"
using namespace std;
#define int long long
int dp[5010][5010];
struct ppp
{
	int a,b,c;
	bool operator <(const ppp &z) const
	{
		if(b-a==z.b-z.a) 
			return c>z.c;
		return b-a>z.b-z.a;
	}
 }p[5010]; 
signed main()
{
	//ios::sync_with_stdio(0);
	//cin.tie(nullptr);
	int n,A,B,C;
	cin>>n>>A>>B>>C;
	for(int i=1;i<=n;i++)
		cin>>p[i].a>>p[i].b>>p[i].c;
	sort(p+1,p+n+1);
	
	for(int i=1;i<=n;i++)
	{
		for(int j=0;j<=min(i,C);j++)
		{
			if (j) dp[i][j] = dp[i - 1][j - 1] + p[i].c;
			
			if(i==j) continue;
			//
			//  if(i==j)  就代表dp[i-1][j]不存在 
			//	i代表遍历了1 到  i 
			//  j代表在   1  到  j 中  取了j个c 
			//  不存在  i<j   如 i=3 j=3  dp[i-1][j]=dp[2][3]  2组卡里,取了3张魔法阵卡
			if (i - j <= B) dp[i][j] = max(dp[i][j], dp[i - 1][j] + p[i].b);
			else dp[i][j] = max(dp[i][j], dp[i - 1][j] + p[i].a);
			
			/*
				if(j)
				也 if(i-j<=B)
				max(dp[i][j],dp[i-1][j]+v[i].b);
				dp[i][j]里面包含当前的p[i].c;
				但dp[i-1][j]+v[i].b不包含当前的p[i].c;
				就是说 dp[i][j]第j个c是v[i].c;
				但 dp[i-1][j]+v[i].b第j个c要不是第i-1个c要不就是第i-1前面的c

			*/
			
			//i遍历到的是1到第i个c
            //i-1遍历到的是1到第i-1个c

		}
	}
	cout<<dp[n][C];
}	
 

代码 2

#include "bits/stdc++.h"
using namespace std;
#define int long long
int dp[5010][5010];
struct ppp
{
	int a,b,c;
	bool operator <(const ppp &z) const
	{
		if(b-a==z.b-z.a) 
			return c>z.c;
		return b-a>z.b-z.a;
	}
 }p[5010]; 
signed main()
{
	//ios::sync_with_stdio(0);
	//cin.tie(nullptr);
	int n,A,B,C;
	cin>>n>>A>>B>>C;
	for(int i=1;i<=n;i++)
		cin>>p[i].a>>p[i].b>>p[i].c;
	sort(p+1,p+n+1);
	// dp[i][j]代表 前 i 组卡中 取 j个c(取j张魔法阵卡) 
	//  不存在  i<j   如 i=3 j=3  dp[i-1][j]=dp[2][3]  2组卡里,取了3张魔法阵卡
	for(int i=0;i<=n;i++)
	{
		for(int j=i+1;j<=n;j++)
			dp[i][j]=-1e9;
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=0;j<=min(i,C);j++)
		{
			if (j) dp[i][j] = dp[i - 1][j - 1] + p[i].c;
			
 
			if (i - j <= B) dp[i][j] = max(dp[i][j], dp[i - 1][j] + p[i].b);
			else dp[i][j] = max(dp[i][j], dp[i - 1][j] + p[i].a);
			
			/*
				if(j)
				也 if(i-j<=B)
				max(dp[i][j],dp[i-1][j]+v[i].b);
				dp[i][j]里面包含当前的p[i].c;
				但dp[i-1][j]+v[i].b不包含当前的p[i].c;
				就是说 dp[i][j]第j个c是v[i].c;
				但 dp[i-1][j]+v[i].b第j个c要不是第i-1个c要不就是第i-1前面的c

			*/
			
			//i遍历到的是1到第i个c
            //i-1遍历到的是1到第i-1个c

		}
	}
	cout<<dp[n][C];
}	
 
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值