2020.09.13 组队训练赛 问题 F: Game of Gnomes

F:侏儒游戏
时间限制:1秒 内存限制: 128 MB

译文描述
敌人及其庞大的军队正在逼近您的堡垒,而您所要捍卫的只是一群守卫地精。赢得这场战斗是没有希望的,所以您的重点将放在对敌人造成尽可能多的伤害上。
您有n个侏儒可供使用。在战斗之前,必须将它们最多分为m个非空组。战斗将依次进行。每回合,您的侏儒都会攻击敌人,对每只活泼的侏儒造成一个单位的伤害。然后,敌人将向m个小组之一投掷雷电进行攻击。闪电杀死该组中的k个地精,如果该组中的活地精少于k个,则全部杀死。当所有的侏儒都死了,战斗就结束了。敌人将始终以最佳方式投掷雷电,以使地精造成的总伤害最小。
现在您想知道,如果以最佳方式将侏儒分为几组,对敌人造成的最大伤害是多少?
例如,如果像在样本输入1中一样,将n = 10个侏儒分为m = 4组,而雷电枪最多造成k = 3伤害,那么最佳解决方案是创建一组大的gnome。大小7和三个大小为1的小组。在第一轮中,造成10点伤害,而闪电将大组减小3。在下一轮中,造成7个伤害,大组减小为大小1。在接下来的四轮中,您分别造成4、3、2和1点伤害,每轮雷电击中一组。总共造成10 + 7 + 4 + 3 + 2 + 1 = 27伤害。
输入
输入由含有三个整数n的单个线,M和K(1≤N≤10 9,1≤M,K≤10 7),其中的含义如上所述。
输出
输出可以对敌人造成的最大伤害。
样例输入 复制
10 4 3
样例输出 复制
27

直接上中文题意:

思路:
容易发现敌方向我方投掷的闪电所造成的伤害只有两种类型:一种是造成k点伤害,另一种则是小于k点伤害。
然后发现所有造成k点伤害的闪电都可以归为同一类型。
然后我们就枚举造成k点伤害的闪电的数量就行了,(小于k点伤害的闪电所造成的伤害应尽可能平均)。

具体细节见代码:

#include<bits/stdc++.h>
using namespace std;
const int N=1e7+15;
typedef long long ll;
int main()
{
    
    ll n,m,k;
    ll maxn=0;
    cin>>n>>m>>k;
    for(int h=max(ll(0),(n/k-m)-10);h<=n/k;h++)
    {
    
        /// op1 : 处理h*k所获得的最大值.
        if( (n-h*k) >= m*k )
            continue;
        ll maxl=n;  ll minl=n-(h-1)*k;  ll ld=h;
        ll op1 = (maxl+minl) * ld /2;

        ll yu=n-h*k;
        ll v=yu/m;
        ll d=yu%m;

        ll temp1=( yu + (m-d)*v+v+1 ) * d /2;

        ll temp2=( v  + (m-d)*v ) * (m-d) /2;

        ll ans= op1 + temp1+temp2;
        maxn=max(maxn,ans);
    }
    cout<<maxn<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43559193/article/details/108566063