洛谷P10387 [蓝桥杯 2024 省 A] 训练士兵
1.My solution
#include <stdio.h>
#include <algorithm>
#include <cmath>
#include <iostream>
#include <set>
#include <string>
#define For(i, j, n) for (int i = j; i <= n; ++i)
template <typename T>
inline T read() {
T x = 0;
int f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-') f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
typedef long long LL;
constexpr int N = 1e5 + 5;
struct Soldier {
int p, c;
Soldier(int p, int c) : p(p), c(c) {}
Soldier() : p(0), c(0) {}
bool operator<(const Soldier& other) const { return c < other.c; }
} soldiers[N];
int n;
LL S, sumofP[N], sumofPC[N];
std::set<int> setofC;
int find(int x) {
int l = 1, r = n;
while(l < r) {
int mid = l + r >> 1;
if(soldiers[mid].c < x)
l = mid + 1;
else
r = mid;
}
return l;
} // 第一个大于等于x的值的位置
LL sumFromVal(int val) {
int pos = find(val);
return (sumofPC[n] - sumofPC[pos - 1]) - (LL)val * (sumofP[n] - sumofP[pos - 1]);
}
int main() {
n = read<int>();
S = read<LL>();
for (register int i = 1; i <= n; i++) {
int p = read<int>(), c = read<int>();
soldiers[i] = Soldier(p, c);
setofC.insert(c);
}
std::sort(soldiers + 1, soldiers + n + 1);
for (int i = 1; i <= n; i++) {
sumofP[i] = sumofP[i - 1] + (LL)soldiers[i].p;
sumofPC[i] = sumofPC[i - 1] + (LL)soldiers[i].c * (LL)soldiers[i].p;
}
LL ans = 1000000000000000000LL;
for (auto val : setofC) {
LL tmpAns = S * val + sumFromVal(val);
ans = std::min(ans, tmpAns);
}
printf("%lld\n", ans);
return 0;
}
因为集体训练和单独训练的转折点肯定是某一批士兵训练完了之后,所以可以用set把c存起来,然后遍历一遍
2. Best solution
注意到c的取值范围比较小,故可以直接用一个桶存起来,这样更快
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
LL n, s, p[N], c[N], cnt[N], Sum, now, ans;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin >> n >> s;
for (int i = 1; i <= n; i++)
cin >> p[i] >> c[i], cnt[c[i]] += p[i], now += p[i], Sum += p[i] * c[i];
for (int i = 1; i <= 1e6; i++) {
if (now < s) break;
ans += s;
Sum -= now;
now -= cnt[i];
}
cout << ans + Sum;
return 0;
}
标签:2024,P10387,int,LL,mid,蓝桥,ch,soldiers,include
From: https://www.cnblogs.com/smartljy/p/18458130