JZ高中OJ 3404. [NOIP2013模拟]卡牌游戏

Description

小X 为了展示自己高超的游戏技巧,在某一天兴致勃勃地找小Y 玩起了一种卡牌游戏。每张卡牌有类型(攻击或防御)和力量值两个信息。

小Y 有n 张卡牌,小X 有m 张卡牌。已知小X 的卡牌全是攻击型的。

游戏的每一轮都由小X 进行操作,首先从自己手上选择一张没有使用过的卡牌X。如果小Y 手上没有卡牌,受到的伤害为X 的力量值,否则小X 要从小Y 的手上选择一张卡牌Y。若Y 是攻击型(当X 的力量值不小于Y 的力量值时才可选择),此轮结束后Y 消失,小Y 受到的伤害为X 的力量值与Y 的力量值的差;若Y 是防御型(当X 的力量值大于Y 的力量值时才可选择),此轮结束后Y 消失,小Y 不受到伤害。

小X 可以随时结束自己的操作(卡牌不一定要用完)。希望聪明的你帮助他进行操作,使得小Y 受到的总伤害最大。
 

Input

输入的第一行包含两个整数n 和m 。

接下来n 行每行包含一个字符串和一个整数,分别表示小Y 的一张卡牌的类型(“ATK”表示攻击型,“DEF”表示防御型)和力量值。

接下来m 行每行包含一个整数,表示小X 的一张卡牌的力量值。

Output

输出一行包含一个整数,表示小Y 受到的最大总伤害。
 

Sample Input

输入1:
2 3
ATK 2000
DEF 1700
2500
2500
2500

输入2:
3 4
ATK 10
ATK 100
ATK 1000
1
11
101
1001
 

Sample Output

输出1:
3000
【样例说明1】
第一轮,小X 选择自己的第一张卡牌和小Y 的第二张卡牌,小Y 的第二张卡牌消失。
第二轮,小X 选择自己的第二张卡牌和小Y 的第一张卡牌,小Y 的第一张卡牌消失,同时受到500 点伤害。
第三轮,小X 选择自己的第三张卡牌,此时小Y 手上已经没有卡牌,受到2500 点伤害。
小X 结束游戏,小Y 共受到3000点伤害。

输出2:
992
【样例说明2】
第一轮,小X 选择自己的第三张卡牌和小Y 的第一张卡牌,小Y 的第一张卡牌消失,同时受到91点伤害。
第二轮,小X 选择自己的第四张卡牌和小Y 的第二张卡牌,小Y 的第二张卡牌消失,同时受到901点伤害。
小X 结束游戏,小Y 共受到992点伤害。
 
 

Data Constraint

各规模均有一半数据满足小Y 只有攻击型卡牌。

对于30%的数据,1≤ n,m ≤ 6。

对于60%的数据,1≤ n,m ≤10^3。

对于100%的数据,1≤ n,m ≤10^5,力量值均为不超过10^6的非负整数。
 1 #include <bits/stdc++.h>
 2 #define ll long long
 3 #define il inline
 4 #define rgi register ll
 5 
 6 using namespace std;
 7 
 8 const int oo = 0x3f3f3f3f;
 9 const ll N = 100000 + 10;
10 
11 ll n, m, step, ans, minn = oo;
12 ll def[N], atk[N], x[N];
13 ll sum_def[N], sum_atk[N], sum_x[N];
14 
15 il ll read()
16 {
17     rgi x = 0, f = 0, ch;
18     while(!isdigit(ch = getchar())) f |= ch == '-';
19     while(isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48), ch = getchar();
20     return f ? -x : x;
21 }
22 
23 int main()
24 {
25     m = read(),n = read();
26     for(rgi i = 1; i <= m; ++i)
27     {
28         char op[10];
29         ll val;
30         scanf("%s %lld", op, &val);
31         if(op[0] == 'A')
32             atk[++atk[0]] = val;
33         else if(op[0] == 'D')
34             def[++def[0]] = val;
35     }
36     for(rgi i = 1; i <= n; ++i)
37         x[i] = read();
38     sort(atk + 1, atk + atk[0] + 1);
39     sort(def + 1, def + def[0] + 1);
40     sort(x + 1, x + n + 1);
41     for(rgi i = 1; i <= atk[0]; ++i)
42         sum_atk[i] = sum_atk[i - 1] + atk[i];
43     for(rgi i = 1; i <= def[0]; ++i)
44         sum_def[i] = sum_def[i - 1] + def[i];
45     for(rgi i = 1; i <= n; ++i)
46         sum_x[i] = sum_x[i - 1] + x[i];
47     atk[atk[0]+1] = oo;
48     for(rgi i = 1; i <= n; ++i)
49     {
50         while(x[i] >= atk[step])
51             step++;
52         step--;
53         minn = min(minn, step + n - i);
54     }
55     ans = sum_x[n] - sum_x[n - minn] - sum_atk[minn];
56     if(minn >= atk[0] && n > m)
57     {
58         step = 1;
59         for(rgi i = 1; i <= def[0]; ++i)
60         {
61             while(def[i] >= x[step])
62                 step++;
63             x[step] = 0;
64         }
65         if(step <= n - minn)
66             for(rgi i = 1; i <= n - minn; ++i)
67                 ans += x[i];
68     }
69     for(rgi i = 1; i < minn; ++i)
70         ans = max(ans, sum_x[n] - sum_x[n - i] - sum_atk[i]);
71     printf("%lld", ans);
72     return 0;
73 }

猜你喜欢

转载自www.cnblogs.com/anbujingying/p/11307968.html