辩论
时间限制: 1 Sec 内存限制: 128 MB
题目描述
一场辩论会开始了,这场辩论会上有两个议题
1
,
2
1,2
1,2。
有
N
N
N 个参加辩论的候选人,每个人对这两个议题都有明确的态度,支持或反对。
作为组织者,小
D
D
D 认真研究了每个候选人,并给每个人评估了一个非负的活跃度,他想让活跃度之和尽可能大。
但是,由于一些不可抗力,选出的候选人必须满足以下两个条件:
- 至少有一半的人支持议题 1 1 1(如果是奇数上取整)。
- 至少有一半的人支持议题 2 2 2。
小 D D D 想知道,在满足以上两个条件的情况下,活跃度之和最大是多少。
输入
第一行一个整数
N
N
N,描述辩论会的候选人。
接下来
N
N
N 行,每行描述一个候选人的态度和活跃度,由一个长度为
2
2
2 的01
串和一个整数
A
i
A_i
Ai组成。01
串中第
i
i
i 位为
0
0
0 表示反对第
i
i
i 个议题,为
1
1
1 表示支持,
A
i
A_i
Ai描述活跃度。
输出
一行一个整数,表示辩论会最大的活跃度。
样例输入
【样例1】
6
11 6
10 4
01 3
00 3
00 7
00 9
【样子2】
6
11 19
10 22
00 18
00 29
11 29
10 28
样例输出
【样例1】
22
【样子2】
105
提示
对于 100 % 100\% 100% 的数据, N ≤ 4 × 1 0 5 , 0 ≤ A i ≤ 5 × 1 0 3 N≤4×10^5,0≤A_i≤5×10^3 N≤4×105,0≤Ai≤5×103
思路
-
11 11 11 肯定是能选的
-
将 01 01 01、 10 10 10 排序,从大到小一对一对的选
-
剩下的 01 01 01、 10 10 10、 00 00 00 从大到小选直到不符合条件
#pragma GCC optimize(3,"Ofast","inline")
#include <iostream>
#include <cstdio>
#include <cstring>
#include <set>
#include <map>
#include <cmath>
#include <queue>
#include <algorithm>
#include <unordered_map>
#include <vector>
using namespace std;
#define ls (rt<<1)
#define rs (rt<<1|1)
typedef long long ll;
template <typename T>
inline void read(T &x) {
x = 0;
static int p;
p = 1;
static char c;
c = getchar();
while (!isdigit(c)) {
if (c == '-')p = -1;
c = getchar();
}
while (isdigit(c)) {
x = (x << 1) + (x << 3) + (c - 48);
c = getchar();
}
x *= p;
}
template <typename T>
inline void print(T x) {
if (x<0) {
x = -x;
putchar('-');
}
static int cnt;
static int a[50];
cnt = 0;
do {
a[++cnt] = x % 10;
x /= 10;
} while (x);
for (int i = cnt; i >= 1; i--)putchar(a[i] + '0');
puts("");
}
const int mod = 1e9+9;
const int inf = 0x3f3f3f3f;
const int maxn = 4e5+10;
vector<int>a,b,c,d;
int n,sum,num;
char s[10];
ll ans;
inline void work() {
scanf("%d", &n);
for (int i = 1, x; i <= n; i++) {
scanf("%s%d", s, &x);
if (s[0] == '1' && s[1] == '1') {
ans += x;
sum++;
num++;
}
if (s[0] == '0' && s[1] == '1') a.emplace_back(x);
if (s[0] == '1' && s[1] == '0') b.emplace_back(x);
if (s[0] == '0' && s[1] == '0') c.emplace_back(x);
}
sort(a.begin(), a.end(), greater<int>());
sort(b.begin(), b.end(), greater<int>());
int mi = min(a.size(), b.size());
for (int i = 0; i < mi; i++) {
ans += a[i] + b[i];
num++;
sum += 2;
}
for (int i = mi; i < a.size(); i++) d.emplace_back(a[i]);
for (int i = mi; i < b.size(); i++) d.emplace_back(b[i]);
for (int i = 0; i < c.size(); i++) d.emplace_back(c[i]);
sort(d.begin(), d.end(), greater<int>());
for (int i = 0; i < d.size(); i++) {
if (num * 2 < sum+1) break;
ans += d[i];
sum++;
}
print(ans);
}
int main() {
//freopen("1.txt","r",stdin);
int T = 1;
//read(T);
while (T--) {
work();
}
return 0;
}