CF796A The Enchanted Forest

有一条有$n$个点的数轴X,每个点有$a_i$个蘑菇,小明可以从任意一点开始,每分钟他做以下操作:

        1. 往左移,往右移,或待在原地 (从位置$x$移到位置$y$,$abs(x-y)<= 1$)

        2. 收集当前位置的蘑菇

        3. 所有位置蘑菇数量$+1$

小明一共有$k$分钟,求可获取最大蘑菇数量

 

分离常数 增量为常数 $\frac{k(k-1)}{2}$ (最优),最优就是一个长度为$k$的最大值区域 (只走线性)

分类分析:

  $k <= n$:

    最优就是一个长度为$k$的最大值区域 + (额外的蘑菇) $\frac{k(k-1)}{2}$

    用滑动窗口 $O(n)$

  $k > n$:

    所有$a_i$的和 + 额外增量 

    考虑逆向计数

      额外增量 = 总增量 - 未获得的增量

        总增量 = $k*n$

      设最后点为$n$,有1个蘑菇未被采集,点 $n-1$ 有$2$个,点$n-2$有$3$个...... 点$1$有$n$个

        未获得的增量 = $\frac{n(n+1)}{2}$

      额外增量 = $k*n$ - $\frac{n(n+1)}{2}$

      

#include <iostream>
#include <cstring>
#include <algorithm>
#define int long long 
using namespace std;
 
void solve(){
    int n, k; cin>>n>>k;
    int ar[n+5];
    for(int i=1;i<=n;i++) cin>>ar[i];
    if(k<=n){
        int l=1, ans=0, cur_sum=0;
        for(int r=1;r<=n;r++){
            cur_sum+=ar[r];
            while((r-l+1)>k){
                cur_sum-=ar[l];
                l++;
            }
            ans=max(ans, cur_sum);
        }
        cout<<ans+(k*(k-1))/2<<endl;
    }else{ 
        int sum=0;
        for(int i=1;i<=n;i++) sum+=ar[i];
        sum += (n*k) - n*(n+1)/2;
        cout<<sum<<endl;
    }
}
 
signed main(){
    int t; cin>>t;
    while(t--){
        solve();
    }
}

 

 

    

      

 

posted @ 2022-10-05 06:01  wd_sun  阅读(45)  评论(0)    收藏  举报