找回密码
 立即注册
首页 业界区 安全 P10387 [蓝桥杯 2024 省 A] 训练士兵

P10387 [蓝桥杯 2024 省 A] 训练士兵

卒挪 昨天 23:05
P10387 [蓝桥杯 2024 省 A] 训练士兵

原题链接
题目范围

\(1 \leq n \leq 10^5\),\(1 \leq p_i, c_i \leq 10^6\),\(1 \leq S \leq 10^{10}\)
解题思路

在每一轮训练中,所有仍需训练的士兵都会参与。这一轮只有两种选择:

  • 进行一次组团训练,花费为 \(S\);
  • 所有参与的士兵各自单独训练一次,花费为当前这些士兵的 \(p_i\) 之和,记为 cur。
因此每一轮的最优花费为 \(\min(S, \text{cur})\)。
关键在于如何维护 cur。
当某个士兵需要训练 \(c_i\) 次时,他会参与前 \(c_i\) 轮训练,并在第 \(c_i\) 轮结束后完成训练,从下一轮开始不再参与。
因此可以预处理数组 loss,其中 loss[x] 表示所有满足 \(c_i = x\) 的士兵,其 \(p_i\) 之和。
初始时,cur 为所有士兵的 \(p_i\) 之和。每一轮结束后,将 cur 减去 loss[当前轮数],即可得到下一轮参与训练士兵的总费用。
复杂度分析

代码实现

[code]void solve(){    LL n,S;    cin>>n>>S;    vectorc(n);    vectorp(n);    int mx=0;    LL  res=0,cur=0;    rep(i,0,n){        cin>>p>>c;        mx=max(mx,c);        cur+=p;    }    vectorloss(mx+1,0);//  总练习次数相同的士兵各单练一次的花费        rep(i,0,n){        loss[c]+=p;    }    rep(i,1,mx+1){        res+=min(S,cur);        cur-=loss;    }    cout

相关推荐

您需要登录后才可以回帖 登录 | 立即注册