

思路:其实每次就是要比较士兵单独训练的价格之和SUM与S的大小,如果 SUM大,那么就减去所有士兵都要训练的次数的最小值,SUM再更新一下,继续比较。
先对士兵的次数按从小到大的次序排序(很重要),再一次遍历士兵,如果遍历到该士兵时,sum>s,那么费用加上所有士兵共同训练的次数*s,由于当前士兵已经结束了,所以sum-=a[i].p;同时共同训练的次数t+=a[i].c;这是为了确保可以算出之后的士兵还要进行多少次的独自训练。
cpp
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e5+5;
int n,s,sum=0,ans=0,t=0;
struct node{
int p;
int c;
}a[N];
bool cmp(node a,node b)
{
return a.c<b.c;
}
signed main()
{
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>n>>s;
for(int i=0;i<n;i++)
{
cin>>a[i].p>>a[i].c;
sum+=a[i].p;
}
sort(a,a+n,cmp);
for(int i=0;i<n;i++)
{
if(sum>s)
{
ans+=s*(a[i].c-t);
t+=a[i].c;
sum-=a[i].p;
//ans+=(a[i].c-t)*a[i].p;
}
else{
ans+=(a[i].c-t)*a[i].p;
}
}
cout<<ans<<endl;
return 0;
}