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(); } }

浙公网安备 33010602011771号