牛客-Maximize The Beautiful Value

https://ac.nowcoder.com/acm/contest/5086/A

大致题意:有一个数组a[i],计算公式为∑a[i]*i,题目要求将a[i+k]往前交换位置到i,然后a[i]到a[i+k-1]往后挪一个单位,重新计算和,寻找最大sum。

思路:一开始按照直接暴力,每一次都加一下但是会超时。(也是暴力)所以运用前缀和,运用前缀和来求区间和,就是从a[i]到a[i+k-1]的区间和,和最开始的∑a[i]*i,然后来计算改变的和并且保存   t=max(t,ans+a[i+k]*i-a[i+k]*(i+k)+sum[i+k-1]-sum[i-1])

总结一下,就是多次访问就用前缀和来优化,可以有效解决复杂度过大问题。

以下是AC代码:

#include<iostream>
#include<cstdio>
#include<algorithm> 
#include<cstring>
using namespace std;
long long sum[100100],a[100100];
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        long long n,k,ans=0;
        memset(sum,0,sizeof(sum));
        scanf(" %lld%lld",&n,&k);
        for(int i=1;i<=n;i++){
            scanf(" %lld",&a[i]);
            sum[i]+=sum[i-1]+a[i];
            ans+=a[i]*i; 
        }
        long long t=-1;
        for(int i=1;i<=n-k;i++){
            t=max(t,ans+a[i+k]*i-a[i+k]*(i+k)+sum[i+k-1]-sum[i-1]);
        }
        printf("%lld\n",t);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/xinpingqihe/p/12663605.html