New Game Plus!
Problem Description
Wabbit is playing a game with n bosses numbered from 1 to n. The bosses can be fought in any order. Each boss needs to be defeated exactly once. There is a parameter called boss bonus which is initially 0.
When the i-th boss is defeated, the current boss bonus is added to Wabbit’s score, and then the value of the boss bonus increases by the point increment ci. Note that ci can be negative, which means that other bosses now give fewer points.
However, Wabbit has found a glitch in the game. At any point in time, he can reset the playthrough and start a New Game Plus playthrough. This will set the current boss bonus to 0, while all defeated bosses remain defeated. The current score is also saved and does not reset to zero after this operation. This glitch can be used at most k times. He can reset after defeating any number of bosses (including before or after defeating all of them), and he also can reset the game several times in a row without defeating any boss.
Help Wabbit determine the maximum score he can obtain if he has to defeat all n bosses.
Input
The first line of input contains two spaced integers n n n and k k k ( 1 ≤ n ≤ 5 ⋅ 1 0 5 1≤n≤5⋅10^5 1≤n≤5⋅105, 0 ≤ k ≤ 5 ⋅ 1 0 5 0≤k≤5⋅10^5 0≤k≤5⋅105), representing the number of bosses and the number of resets allowed.
The next line of input contains n n n spaced integers c 1 , c 2 , … , c n c_1,c_2,…,c_n c1,c2,…,cn ( − 1 0 6 ≤ c i ≤ 1 0 6 −10^6≤c_i≤10^6 −106≤ci≤106), the point increments of the n bosses.
Output
Output a single integer, the maximum score Wabbit can obtain by defeating all n bosses (this value may be negative).
Sample Input
13 2
3 1 4 1 5 -9 -2 -6 -5 -3 -5 -8 -9
Sample Output
71
题意
一个闯关游戏,共有n个Boss。初始tmp=0,每一回合开始,最终得分sc+=tmp,主角可以选择一个存活的Boss,击败它后,tmp+=ci。同时主角还可以有最多k次将tmp变为0的机会,求最后能得到的最大的sc。
思路
将每次tmp置0,称为一轮。设某一轮有len个回合,依次选择为
i
1
,
i
2
.
.
.
i
l
e
n
i_1,i_2...i_{len}
i1,i2...ilen,则最终对于sc的贡献为
c
i
1
∗
(
l
e
n
−
1
)
+
c
i
2
∗
(
l
e
n
−
2
)
+
.
.
.
.
+
c
i
l
e
n
∗
(
l
e
n
−
l
e
n
)
c_{i_1}*(len-1)+c_{i_2}*(len-2)+....+c_{i_{len}}*(len-len)
ci1∗(len−1)+ci2∗(len−2)+....+cilen∗(len−len)。
先对c排序。对于
c
i
≥
0
c_i\ge0
ci≥0,应该把他们放在同一轮,并按降序排列。同时为了让贡献尽量大,还可以考虑另len更大,该轮按降序选择若干个
c
i
≤
0
c_i\le0
ci≤0的Boss,直至
t
m
p
<
0
tmp<0
tmp<0。
计算完上面一部分的贡献后,考虑
c
i
<
0
c_i<0
ci<0的Boss(
t
m
p
<
0
tmp<0
tmp<0,考虑将其作为一个新的Boss,
c
i
=
t
m
p
c_i = tmp
ci=tmp)。根据上面的公式,
c
i
c_i
ci越靠后,对sc造成的负面影响越小。最多可以有
k
+
1
k+1
k+1轮,依次将
c
i
c_i
ci放到每一轮的最后一个,倒数第二个…即可。
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<map>
#include<vector>
#include<queue>
#include<iterator>
#define dbg(x) cout<<#x<<" = "<<x<<endl;
#define INF 0x3f3f3f3f
#define LLINF 0x3f3f3f3f3f3f3f3f
#define eps 1e-6
using namespace std;
typedef long long LL;
typedef pair<int, int> P;
const int maxn = 500100;
const int mod = 998244353;
int a[maxn];
LL solve(int n, int m);
int main()
{
int n, m, i, j, k;
scanf("%d %d", &n, &m);
for(i=0;i<n;i++)
scanf("%d", &a[i]);
printf("%I64d\n", solve(n, m+1));
return 0;
}
LL solve(int n, int m)
{
int i, j, k;
LL ans, tmp;
ans = tmp = 0;
sort(a, a+n);
for(i=n-1;i>=0;i--){
ans += tmp;
tmp += a[i];
if(tmp < 0)break;
}
if(i == -1)return ans;
a[i] = tmp;
n = i+1;
for(i=0;i<n;i++)
ans += 1LL*(i/m)*a[i];
return ans;
}