题解
可以发现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;
}