codeforces B. Ciel and Duel

本文介绍了一个卡片游戏中的战斗策略,通过分析玩家手上的攻击和防御卡片属性,利用贪心算法来计算对对手造成最大伤害的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

B. Ciel and Duel
 

Fox Ciel is playing a card game with her friend Jiro.

Jiro has n cards, each one has two attributes:position (Attack or Defense) and strength. Fox Ciel has m cards, each one has these two attributes too. It's known that position of all Ciel's cards is Attack.

Now is Ciel's battle phase, Ciel can do the following operation many times:

  1. Choose one of her cards X. This card mustn't be chosen before.
  2. If Jiro has no alive cards at that moment, he gets the damage equal to (X's strength). Otherwise, Ciel needs to choose one Jiro's alive cardY, then:
    • If Y's position is Attack, then (X's strength) ≥  (Y's strength) must hold. After this attack, cardY dies, and Jiro gets the damage equal to (X's strength) - (Y's strength).
    • If Y's position is Defense, then (X's strength) >  (Y's strength) must hold. After this attack, cardY dies, but Jiro gets no damage.

Ciel can end her battle phase at any moment (so, she can use not all her cards). Help the Fox to calculate the maximal sum of damage Jiro can get.

Input

The first line contains two integers n andm (1 ≤ n, m ≤ 100) — the number of cards Jiro and Ciel have.

Each of the next n lines contains a stringposition and an integer strength (0 ≤ strength ≤ 8000) — the position and strength of Jiro's current card. Position is the string "ATK" for attack, and the string "DEF" for defense.

Each of the next m lines contains an integerstrength (0 ≤ strength ≤ 8000) — the strength of Ciel's current card.

Output

Output an integer: the maximal damage Jiro can get.

Sample test(s)
Input
2 3
ATK 2000
DEF 1700
2500
2500
2500
Output
3000
Input
3 4
ATK 10
ATK 100
ATK 1000
1
11
101
1001
Output
992

 这道题我用的是贪心的思路,分两种情况,但是分的还是不够彻底,然后就老是错,后来看了别人的代码,还是给两种情况没有彻底分开了写的,总体来说就是思路不清晰的,
思路:贪心,
分两种情况:
一    对于防御的牌不用管,只考虑战胜对方的atk牌的,这时候就是最基本的贪心,用自己的最大牌去袭击对方的最小牌,取得对方袭击的最大。
二   即去除对方的防御牌,然后在战胜对方的atk牌,然后自己手里剩下的牌就是多可以增大对方的伤害数,所以满足的条件最少是n>m,然后用贪心使尽可能小的牌去战胜对方的防御牌,然后判断手中牌是否可以战胜对方手中剩下的atk牌
取两种方式的最大牌.
下面是代码:

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<stack>
#include<vector>
#include<climits>
#include<map>
using namespace std;
#define rep(i,n) for(int i=0; i<n; i++)
#define repf(i,n,m) for(int i=(n); i<=(m); ++i)
#define repd(i,n,m) for(int i=(n); i>=(m); --i)
#define fab(a) ((a)>0?(a):(0-(a)))
#define ll long long
#define arc(a) ((a)*(a))
#define inf 100000
#define exp 0.000001
#define N 
vector<int>atk;
vector<int>def;
vector<int>ciel;
vector<bool>sign;
int n,m;
int part()
{
	int sum=0;
	int len=atk.size();
//	cout<<len<<" "<<n<<endl;
//	cout<<"@@@"<<endl;
	int t=min(len,n);
	rep(i,t)
	{
//		cout<<i<<endl;getchar();
		sum+=max(0,ciel[n-1-i]-atk[i]);
	}
//	cout<<sum<<endl;
	return sum;
}
int find(int x)
{
	rep(i,n)
		if(sign[i]==true && ciel[i]>=x)
			return i;
	return -1;
}
int all()
{
	int len=def.size();
	if(len>n)
		return 0;
	int sum=0;
	rep(i,len)
	{
		int x=find(def[i]+1);
		if(x==-1)
			return 0;
		sign[x]=false;
	}
	len=atk.size();
	rep(i,len)
	{
		int x=find(atk[i]);
		if(x==-1)
			return 0;
		sum+=ciel[x];
		sign[x]=false;
	}
	rep(i,n)
		if(sign[i]==true)
			sum+=ciel[i];
    rep(i,len)
		sum-=atk[i];
//	cout<<sum<<endl;
	return sum;
}
int main()
{ 
	char s[5];
	int x;
	while(cin>>m>>n)
	{
		atk.clear();
		def.clear();
		ciel.clear();
		sign.clear();
		rep(i,m)
		{
          cin>>s>>x;
	      if(s[0]=='A')
		     atk.push_back(x);
	      else
		     def.push_back(x);	  
		}
		rep(i,n)
		{
			cin>>x;
			ciel.push_back(x);
			sign.push_back(true);
		}
		sort(atk.begin(),atk.end());
		sort(def.begin(),def.end());
		sort(ciel.begin(),ciel.end());
		int r=max(part(),all());
		cout<<r<<endl;
	}
   return 0;
}
  


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

淡定的小Y

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值