P11231 [CSP-S 2024] 决斗
题目描述
今天是小 Q 的生日,他得到了 nnn 张卡牌作为礼物。这些卡牌属于火爆的“决斗怪兽”,其中,第 iii 张卡代表一只攻击力为 rir_iri,防御力也为 rir_iri 的怪兽。
一场游戏分为若干回合。每回合,小 Q 会选择某只怪兽 iii 以及另一只怪兽 j(i≠j)j(i \neq j)j(i=j),并让怪兽 iii 向怪兽 jjj 发起攻击。此时,若怪兽 iii 的攻击力小于等于怪兽 jjj 的防御力,则无事发生;否则,怪兽 jjj 的防御被打破,怪兽 jjj 退出游戏不再参与到剩下的游戏中。一只怪兽在整场游戏中至多只能发起一次攻击。当未退出游戏的怪兽都已发起过攻击时,游戏结束。
小 Q 希望决定一组攻击顺序,使得在游戏结束时,未退出游戏的怪兽数量尽可能少。
输入格式
输入的第一行包含一个正整数 nnn,表示卡牌的个数。
输入的第二行包含 nnn 个正整数,其中第 iii 个正整数表示第 iii 个怪兽的攻击力及防御力 rir_iri。
输出格式
输出一行包含一个整数表示游戏结束时未退出游戏的怪兽数量的最小值。
输入输出样例 #1
输入 #1
5
1 2 3 1 2
输出 #1
2
输入输出样例 #2
输入 #2
10
136 136 136 2417 136 136 2417 136 136 136
输出 #2
8
说明/提示
【样例 1 解释】
其中一种最优方案为:第一回合让第 222 只怪兽向第 111 只怪兽发起攻击,第二回合让第 555 只怪兽向第 444 只怪兽发起攻击,第三回合让第 333 只怪兽向第 555 只怪兽发起攻击。此时没有退出游戏的怪兽都进行过攻击,游戏结束。可以证明没有更优的攻击顺序。
【样例 3】
见选手目录下的 duel/duel3.in 与 duel/duel3.ans。
该样例满足 ∀1≤i≤n,ri≤2\forall 1 \leq i \leq n, r_i \leq 2∀1≤i≤n,ri≤2。
【样例 4】
见选手目录下的 duel/duel4.in 与 duel/duel4.ans。
【数据范围】
对于所有测试数据,保证:1≤n≤1051 \leq n \leq 10^51≤n≤105,1≤ri≤1051 \leq r_i \leq 10^51≤ri≤105。
测试点 | nnn | rir_iri | 特殊性质 |
---|---|---|---|
1∼41\sim 41∼4 | ≤10\leq 10≤10 | ≤105\leq 10^5≤105 | 无特殊性质 |
5∼105\sim 105∼10 | ≤105\leq 10^5≤105 | ≤2\leq 2≤2 | 无特殊性质 |
11∼1511\sim 1511∼15 | ≤30\leq 30≤30 | ≤105\leq 10^5≤105 | 特殊性质 A |
16∼2016\sim 2016∼20 | ≤105\leq 10^5≤105 | ≤105\leq 10^5≤105 | 无特殊性质 |
特殊性质 A:保证每个 rir_iri 在可能的值域中独立均匀随机生成。
题解
观察到:
- 如果所有怪兽的攻击力都不同,那么攻击力最高的怪兽无法被淘汰
- 如果有多个相同攻击力的怪兽,它们之间无法互相淘汰
- 最终剩下的怪兽数量等于攻击力值的出现次数的最大值
最终代码:
#include "bits/stdc++.h"
using namespace std;
const int N = 1e6+7;
int r[N], x[N], n;
int main(){
cin>>n;
int mxn = 0;
for(int i=1;i<=n;++i){
cin>>r[i];
mxn = max(mxn, r[i]);
x[r[i]] ++;
}
int maxn = 0;
for(int i=1;i<=mxn;++i){
maxn = max(maxn, x[i]);
}
cout<<maxn<<endl;
return 0;
}