[题解]CF1824A LuoTianyi and the Show
思路
首先,我们需要确定每一种方案的第一个人,那么,可以分为三种情况(其中 为 的数量, 为 的数量, 为原序列 中权值大于 的序列排序并离散化的数量):
- 选择 的人开始。那么,会在 点坐下,那么,对于所有 的人都没有位置坐。想象一下他们坐下的顺序,如果当前 ,并且有一个 (即当前需要选择的位置),那么,显然优先选择 坐。所以,此贡献为 。
- 选择 的人开始,同理,贡献为 。
- 选择 的人开始,那么,能够在 左边坐下的人,要么 要么是 ;右边同理。所以,对于左边的答案 是 ,右边的答案 同理 。该位置的贡献是 。
在这里,我们排序并且离散化的意义是,使第 中情况中,快速得出 和 的数量。
Code
#include <bits/stdc++.h>
#define re register
using namespace std;
const int N = 1e5 + 10;
int T,n,m;
inline int read(){
int r = 0,w = 1;
char c = getchar();
while (c < '0' || c > '9'){
if (c == '-') w = -1;
c = getchar();
}
while (c >= '0' && c <= '9'){
r = (r << 3) + (r << 1) + (c ^ 48);
c = getchar();
}
return r * w;
}
int main(){
T = read();
while (T--){
int a = 0,b = 0,ans = 0;
vector<int> t,arr;
n = read();
m = read();
for (re int i = 1;i <= n;i++){
int x;
x = read();
if (x == -1) a++;
else if (x == -2) b++;
else t.push_back(x);
}
int len = t.size();
sort(t.begin(),t.end());
for (re int i = 0;i < len;i++){
if (!i) arr.push_back(t[i]);
else if (t[i] != t[i - 1]) arr.push_back(t[i]);
}//排序 + 离散化
len = arr.size();
for (int i = 0;i < len;i++){
int A = 0,B = 0;
if (a + i <= arr[i] - 1) A = a + i;
else A = arr[i] - 1;
if (b + len - i - 1 <= m - arr[i]) B = b + len - i - 1;
else B = m - arr[i];
ans = max(ans,A + 1 + B);
}
printf("%d\n",max({ans,min(m,a + len),min(m,b + len)}));//3 种情况取最大值
}
return 0;
}
作者:WaterSun
出处:https://www.cnblogs.com/WaterSun/p/18266716
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
分类:
题解
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】