二分:
若某个团练次数可以让所有士兵完成训练任务,则更多次的团练次数也可以完成所有任务。二分找到最小的团练次数使得所有士兵能完成任务且单独训练的金币数不比单次团练多即可,最后记得计算总的金币数因为题目问的是这个。
#include <iostream>
using namespace std;
const int N = 100010;
typedef pair<long long,long long> PII;
long long n, m, ans;
PII a[N];
bool check(int u)
{
long long sum = 0;
for(int i = 1; i <= n; i ++)
{
if(a[i].second - u > 0) sum += a[i].first;
}
if(sum <= m) return true;
else return false;
}
int main()
{
scanf("%lld %lld", &n, &m);
long long mx = -N;
for(int i = 1; i <= n; i ++)
{
long long x, y;
scanf("%lld %lld", &x, &y);
a[i].first = x, a[i].second = y;
if(a[i].second > mx) mx = a[i].second;
}
long long l = 0, r = mx;
while(r - l > 0)
{
long long mid = (l + r) / 2;
if(check(mid)) r = mid;
else l = mid + 1;
}
for(int i = 1; i <= n; i ++)
{
if(a[i].second-l > 0) ans += a[i].first*(a[i].second-l);
}
printf("%lld", ans + m*l);
return 0;
}