Day4 T2 카드 게임

이름

  작은 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;
}

추천

출처www.cnblogs.com/znk161223/p/11516672.html