CF321B Solution

题目链接

题解

可以发现Ciel所处如下三种情况之一:①无法击灭对方全部攻击卡牌;②可以击灭全部攻击卡牌,但无法击灭防御;③可以击灭对方全部卡牌。

对于第一种情况则尽力使双方卡牌权值差最大,使用田忌赛马策略使用我方最优卡牌攻击敌方最劣卡牌。对于第二种情况则使我方击灭对方全部攻击卡牌即可,以最优攻击最优。对于第三种情况需使防御卡牌所浪费的权值最小,使用权值尽量接近的卡牌攻击敌方防御,使用第二种情况的策略攻击敌方攻击,剩余直接造成伤害。于三种情况中取伤害最大为答案。

AC代码

#include<bits/stdc++.h>
using namespace std;
const int N=110;
struct node {int v,p;} a[N];//依权值由小到大排序,p=1/0(防御/进攻)
int b[N];
bool cmp(node a,node b) {return a.v<b.v;}
int main()
{
	int n,m; string op;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	{
		cin>>op; scanf("%d",&a[i].v);
		if(op=="DEF") a[i].p=1;
	}
	for(int i=1;i<=m;i++) scanf("%d",&b[i]);
	sort(a+1,a+n+1,cmp); sort(b+1,b+m+1); 
    //情况1
	int pos=m,ans=0,sum=0;
	for(int i=1;i<=n;i++)
	{
		if(a[i].p) continue;
		if(b[pos]<a[i].v || !pos) break;
		ans+=(b[pos--]-a[i].v); 
	}
    //情况2
	pos=m;
	for(int i=n;i>=1;i--)
	{
		if(a[i].p) continue;
		if(b[pos]<a[i].v || !pos) break;
		sum+=(b[pos--]-a[i].v);
	}
	ans=max(ans,sum); 
    //情况3
	sum=0,pos=0;
	for(int i=1;i<=n;i++)
	{
		if(!a[i].p) continue;
		while(b[pos]<=a[i].v && pos<=m) pos++;
		if(pos>m) {printf("%d",ans); return 0;}
		b[pos++]=0;
	}
	sort(b+1,b+m+1); pos=m;
	for(int i=n;i>=1;i--)
	{
		if(a[i].p) continue;
		if(b[pos]<a[i].v || !pos) {printf("%d",max(ans,sum)); return 0;}
		sum+=(b[pos--]-a[i].v);
	}
	for(int i=1;i<=pos;i++) sum+=b[i];
	ans=max(ans,sum);
	printf("%d",ans);
	return 0;
}
posted @ 2021-03-08 20:14  violet_holmes  阅读(58)  评论(0编辑  收藏  举报