cf1175D. Array Splitting(将数组分成k部分 所有数的值*他所在的第几个部分 和最大 拆式子)

题目
在这里插入图片描述
我就是个弱智。哭了。唉。怎么就是想不到拆开式子呢? 拆开之后很简单。

sum=s[r1]*1+(s[r2]-s[r1])*2+(s[r3]-s[r2])*3+....+(s[rk-1]-s[rk-2])*(k-1)+(s[n]-s[rk-1])*k;
把括号打开
sum=k*s[n]-s[r1]-s[r2]-...s[rk-1];
为了使sum尽可能大就选前k-1个前缀和即可 
那么就对前缀和有小到大排序。。 
前k-1个前缀和直接对前缀sum数组排序即可。就没有打乱顺序,就是按排序后的为k-1个分界点。
#include<bits/stdc++.h>
#define m(a,b) memset(a,b,sizeof a)
using namespace std;
typedef long long ll;
const int N=3e5+5;
ll sum[N];
int main(){
    int n,k;scanf("%d%d",&n,&k);
    for(int i=1,x;i<=n;++i) scanf("%d",&x),sum[i]=sum[i-1]+x;
    ll ans=(ll)k*sum[n];
    sort(sum+1,sum+n-1+1);
    --k;
    for(int i=1;k;--k,++i) ans-=sum[i];
    printf("%lld\n",ans);
}
©️2020 CSDN 皮肤主题: 终极编程指南 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值