• 小 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
    			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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58

    代码 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
    	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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
  • 相关阅读:
    drools中then部分的写法
    在Windows操作系统中怎样使用nc命令
    跨平台应用开发进阶(四十五)uni-app集成企微客服实战
    C/C++中的协程
    面经汇总--校招--北京顺丰同城
    Oracle数据库体系结构(三)_逻辑结构
    [杂记]关于C++中类继承的一些理解
    “转型做 Saas 失败后,我们归档了 5700+Star 的 GitHub 项目!”
    Node.js_基础知识(计算机硬件基础)
    2023 Google 开发者大会 – AI 领域的技术更新
  • 原文地址:https://blog.csdn.net/weixin_53623850/article/details/127894235