Game of Gnomes(贪心题)

训练赛题目,记录在这里,下面是题面:

The enemy and their massive army is approaching your fortress, and all you have to defend it is a legion of guardian gnomes. There is no hope of winning the battle, so your focus will instead be on causing as much damage as possible to the enemy.
(此处有一张地精图片)
You have n gnomes at your disposal. Before the battle, they must be divided into at most m non-empty groups. The battle will then proceed in turns. Each turn, your gnomes will attack the enemy, causing one unit of damage for each living gnome. Then the enemy will attack by throwing a lightning bolt at one of the m groups. The lightning bolt kills k of the gnomes in that group, or all of them if the number of living gnomes in the group is less than k. The battle ends when all gnomes are dead. The enemy will always throw the lightning bolts in an optimal way such that the total damage caused by the gnomes is minimized.

Now you wonder, what is the maximum amount of damage you can cause to the enemy if you divide the gnomes into groups in an optimal way?

For example, if as in Sample Input 1 you have n = 10 gnomes that are to be divided into m = 4 groups, and the lightning bolt does at most k = 3 damage, then an optimal solution would be to create one large group of size 7 and three small groups of size 1. In the first round, you cause 10 damage and the lightning bolt reduces the large group by 3. In the next round, you cause 7 damage and the large group is reduced down to size 1. In the remaining four rounds you do 4, 3, 2, and 1 damage respectively and the lightning bolt removes one group each round. In total you do 10 + 7 + 4 + 3 + 2 + 1 = 27 damage.
Input

The input consists of a single line containing the three integers n, m, and k (1 ≤ n ≤ 10⁹, 1 ≤ m, k ≤ 10⁷), with meanings as described above.
Output

Output the maximum amount of damage you can cause to the enemy.
样例输入1

10 4 3

样例输出1

27

样例输入2

5 10 100

样例输出2

15

大致题意:

题的大致意思为有n个地精,最多分成m个组,然后每次攻击每个地精造成一点伤害,造成伤害以后会有一道闪电劈一组地精,造成K点伤害,也就是这个组里减少k个地精,闪电一定会挑地精最多的组劈。

大致思路:

本题的思路是首先选出一部分地精,组成a组,每组k个地精,然后将剩下的地精平均分到min(m,n)组里,选取每一个可行的a值,求出最大值即可。

下面是ac代码:

#include 
using namespace std;
typedef long long ll;
ll F(ll a)
{
    if(a%2==0)return a/2*(a+1);
    else return (a+1)/2*a;
}
int main()
{
    ll numbers,groups,damage;cin>>numbers>>groups>>damage;
    ll m=min(numbers,groups);
    ll ans=0;
    for(ll i=0;numbers-damage*i>=0;i++)
    {
        if(numbers-damage*i>(damage-1)*m)continue;
        ll t=(damage+damage*i)*i/2+(numbers-damage*i)*i+(numbers-damage*i)/m*F(m)+F(numbers-damage*i-(numbers-damage*i)/m*m);
        if(t>ans)ans=t;
    }
    cout<

你可能感兴趣的:(个人题解,算法)