이름
작은 X 게임의 자신의 뛰어난 능력을 보여주기 위해, 어느 날 행복하게 카드 게임을 작은 Y를 찾을 수 있습니다. 각 카드는 유형 (공격 또는 방어)와 두 개의 전원 값 정보가 있습니다. 작은 카드 Y의 N-카드, 소형 카드 X는 m이 있습니다. X는 공격의 모든 유형 작은 카드를 알려져 있습니다.
작은 X 운영하여 게임의 각 라운드는 먼저 그의 손 X.에서 사용하지 않는 카드를 선택 당신이 작은 Y 카드, X의 값의 능력에 손상을하지 않은 경우 Y를, 그렇지 않으면 작은 X는 작은 손 카드 Y.에서 선택 (X의 값은 선택 Y 전력의 값 이상인 경우에만 전력) Y 공격하는 경우, Y의 현재 라운드 종료 후 사라 Y 작은 손상이 X와 Y의 전력 값의 전력 값 사이의 차이이고; Y 만약 방어 형 (X의 값이 Y 력 수치 선택할 이상에만 전원), Y의 현재 라운드의 종료 후, Y가 작은 상처없는 사라졌다.
X는 언제든지 자신의 작은 동작 (카드를 밖으로 실행하지 않아도) 종료 될 수 있습니다. 스마트 희망 당신은 그를 위험에 그래서 총 손상 작은 Y를 운영되도록 지원한다.
PS : 원래 제목 : CF321B 시엘과 결투
기입
입력의 첫 번째 라인은 두 정수 n 및 m을 포함한다.
다음 N 개의 라인 카드의 작은 Y 형과 강도 값 ( "ATK는"공격 "DEF"를 나타내는 방어 나타냄) 각각 문자열과 정수를 포함한다.
다음 m 라인 X의 카드 값의 전력이 작은 나타내는 정수를 포함한다.
수출
출력 라인은 작은 Y. 입은 최대 총 손상을 나타내는 정수를 포함
견본
기입 | 수출 |
---|---|
3 2 ATK 2000 DEF 1700 2500 2500 2500 |
3000 |
3 4 ATK 10 ATK 100 ATK 1000 1 11 101 1,001 |
992 |
스케일 데이터
모든 규모의 절반은 작은 데이터가 Y에만 공격 카드를 만족합니다.
데이터, 1≤n, m≤6의 30 %.
데이터의 60 %, 1 ≦ N, m의 ≤를 들어 \ (제 3 ^ \) .
데이터의 100 %, 1 ≦ N, m ≤ 용의로 \ (10 ^ 5 \) , 전력 값 이상없는 \ (10 ^ 6 \) 음이 아닌 정수.
문제 해결
: 두 가지 전략을 고려
1. 방어 플레이어의 다른면을 고정 및 재생이 중단 될 때까지 우리의 가장 큰 카드로 직접 작은 공격 카드를 공격한다.
2. 다음 손상의 원인이 고갈 모든 카드를 서로 가장 가까운 카드의 크기는 카드의 나머지 부분을 채웠다.
그것은이 두 가지 전략 더 나은 의사 결정을하기가 어렵습니다, 나는 어떻게해야합니까?
- 매우 간단합니다, 두 가지 전략은 더 나은 해답을 고려하여 다시 사용한다.
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
const int MAXN=100010;
int n,m,cntatk,cntdef;
int a[MAXN],atk[MAXN],def[MAXN];
bool book[MAXN]={false};
ull ans1=0,ans2=0;
void solve1(){
for(int i=1,j=m;a[j]>atk[i] && j>0 && i<=cntatk;i++,j--) ans1+=a[j]-atk[i];
}
void solve2(){
for(int i=1,j=1;i<=cntdef;i++){
while((a[j]<=def[i] || book[j]) && j<=m) j++;
if(j==m+1){
ans2=0;//如果连对方的防御牌都打不完,这种策略的得分为0
return;
}
book[j]=true;
}
for(int i=1,j=1;i<=cntatk;i++){
while((a[j]<atk[i] || book[j]) && j<=m) j++;
if(j==m+1) return;//如果打不完对方攻击牌,直接退出
ans2+=a[j]-atk[i];
book[j]=true;
}
for(int i=1;i<=m;i++){
if(!book[i]) ans2+=a[i];
}
}
int main(){
scanf("%d %d",&n,&m);
char ch[5];
int t;
for(int i=1;i<=n;++i){
scanf("%s %d",ch,&t);
if(ch[0]=='A') atk[++cntatk]=t;
else def[++cntdef]=t;
}
for(int i=1;i<=m;i++) scanf("%d",&a[i]);
sort(atk+1,atk+cntatk+1);
sort(def+1,def+cntdef+1);
sort(a+1,a+m+1);
solve1();
solve2();
printf("%lld",max(ans1,ans2));
return 0;
}