清北学堂模拟赛d2t4 最大值(max)
題目描述
LYK有一本書,上面有很多有趣的OI問題。今天LYK看到了這么一道題目:
這里有一個長度為n的正整數數列ai(下標為1~n)。并且有一個參數k。
你需要找兩個正整數x,y,使得x+k<=y,并且y+k-1<=n。并且要求a[x]+a[x+1]+…+a[x+k-1]+a[y]+a[y+1]+…+a[y+k-1]最大。
LYK并不會做,于是它把題扔給了你。
輸入格式(max.in)
第一行兩個數n,k。
第二行n個數,表示ai。
輸出格式(max.out)
兩個數表示x,y。若有很多種滿足要求的答案,輸出x最小的值,若x最小仍然還有很多種滿足要求的答案,輸出y最小的值。
輸入樣例
5 2
6 1 1 6 2
輸出樣例
1 4
對于30%的數據n<=100。
對于60%的數據n<=1000
對于100%的數據1<=n<=100000,1<=k<=n/2,1<=ai<=10^9。
分析:一個O(n^3)的做法,直接枚舉兩個區間,再枚舉求區間和.因為用到了區間和,所以可以用前綴和優化到O(n^2).然后可以發現這個區間長度是固定的,我們可以在挪動右端點的時候右邊每加一個數,左邊彈一個數,用O(n)的時間處理出每一段長度為k的區間的和,在處理的過程中可以順便記錄j-k之前的區間最大值,一邊求和一邊統計答案就可以了.
#include <bits/stdc++.h>using namespace std;int n,k,lastt = 1,x,y; long long a[100010],r[100010],Max,sum,ans;int main() {freopen("max.in","r",stdin);freopen("max.out","w",stdout);scanf("%d%d",&n,&k);for (int i = 1; i <= n; i++)scanf("%lld",&a[i]);for (int i = 1; i <= n; i++){sum += a[i];if (i - k > 0)sum -= a[i - k];r[i] = sum;if (i - k > 0){if (Max < r[i - k]){Max = max(Max,r[i - k]);lastt = i - k;}}if (Max + r[i] > ans){ans = max(ans,Max + r[i]);x = max(1,lastt - k + 1);y = max(1,i - k + 1);}}printf("%d %d\n",x,y);return 0; }?
轉載于:https://www.cnblogs.com/zbtrs/p/7622978.html
總結
以上是生活随笔為你收集整理的清北学堂模拟赛d2t4 最大值(max)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 配置虚拟机 Linux 静态IP
- 下一篇: C#.NET常见问题(FAQ)-如何使用