“蔚来杯“2022牛客暑期多校训练营5 I.Board Game

原题指路

求点击

题目大意

n ( 1 ≤ n ≤ 1 0 9 ) n(1 \leq n \leq 10^9) n(1n109) 个士兵攻击魔法师,这些士兵初始分为 m ( 1 ≤ m ≤ 1 0 7 ) m(1 \leq m \leq 10^7) m(1m107) 组,每组至少 1 1 1 人。
每一回合,每个存活的士兵会对魔法师造成 1 1 1 点伤害。之后魔法师选择一组士兵,击杀其中最多 k ( 1 ≤ k ≤ 1 0 7 ) k(1 \leq k \leq 10^7) k(1k107) 人。
魔法师很聪明,总会采用最后策略。
如果士兵最终造成的最大总伤害不小于 x ( 1 ≤ x ≤ 1 0 13 ) x(1 \leq x \leq 10^{13}) x(1x1013),则输出“YES”和可能造成的最大总伤害 。否则输出“NO”。

题解

显然的,在魔法师一次就能消灭任意小组的情况下,在将其平均分成 m m m 个小组的情况是最优的,
一组大小为 x + k x+k x+k 的士兵可以分为一组大小为 x x x 的士兵和一组大小为 k k k 的士兵,
而除 k k k 外剩下的小组人数相等时是最优的,所以我们可以跑循环得出满足的 a a a 使得 a k + m x = n ( x < k ) ak+mx=n (x < k) ak+mx=n(x<k)
然后通过一定的配对计算出答案,通过计算可知, ( n / k − m ) ≤ a ≤ ( n / k ) (n/k-m) \leq a \leq (n/k) (n/km)a(n/k)

代码

#include<bits/stdc++.h>
#define ll long long
#define int long long
using namespace std;
int n,m,a,x,k;
ll ans1;
void solve(ll x)
{
    ll b=n-x*k;
    ll y=b%m,c=m-y,d=b/m,sum=0;
    sum+=(n+(n-x*k+k))*x/2;                 //x部分
    sum+=((n-x*k)+(n-x*k-y*(d+1)+d+1))*y/2;         //余数部分
    sum+=((c*d)+(d))*c/2;                      //a部分
    ans1=max(ans1,sum);
}
signed main()
{
    scanf("%lld%lld%lld%lld",&n,&m,&k,&x);
    for(ll r=n%k,p=n%k;p<=n&&p<=r+m*k;p+=k)   //寻找满足条件的 a
        solve((n-p)/k);
    if(ans1<x)
        puts("NO");
    else
        printf("YES %lld",ans1);
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值