题目描述
最近有 n n n 个不爽的事,每句话都有一个正整数刺痛值(心理承受力极差)。爱与愁大神想知道连续 m m m 个刺痛值的和的最小值是多少,但是由于业务繁忙,爱与愁大神只好请你编个程序告诉他。
输入格式
第一行有两个用空格隔开的整数,分别代表 n n n 和 m m m。
第 2 2 2 到第 ( n + 1 ) (n + 1) (n+1) 行,每行一个整数,第 ( i + 1 ) (i + 1) (i+1) 行的整数 a i a_i ai 代表第 i i i 件事的刺痛值 a i a_i ai。
输出格式
输出一行一个整数,表示连续 m m m 个刺痛值的和的最小值是多少。
样例输入
8 3
1
4
7
3
1
2
4
3
样例输出
6
数据规模与约定
- 对于 30 % 30\% 30% 的数据,保证 n ≤ 20 n \leq 20 n≤20。
- 对于 60 % 60\% 60% 的数据,保证 n ≤ 100 n \leq 100 n≤100。
- 对于 90 % 90\% 90% 的数据,保证 n ≤ 1 0 3 n \leq 10^3 n≤103。
- 对于 100 % 100\% 100% 的数据,保证 0 ≤ m ≤ n ≤ 3 × 1 0 3 0 \leq m \leq n \leq 3 \times 10^3 0≤m≤n≤3×103, 1 ≤ a i ≤ 100 1 \leq a_i \leq 100 1≤ai≤100。
参考代码
/*
多次区间查询,适合使用前缀和来解决。
前缀和:一个数列前i项的和
如果用s[i]表示数组a前i项的和,那么s[i] = a[1]+a[2]+...+a[i]
假设数组a中的元素依次是:1 1 1 1 1 1 1
那么a的前缀和数组s就是: 1 2 3 4 5 6 7
*/
#include<iostream>
using namespace std;
int a[3005], minV = 2147483647, s;
int main() {
int n, m;
cin >> n >> m;
//因为计算前缀和公式是a[i] = a[i] + a[i - 1],所以,i从1开始,以免下标越界
for (int i = 1; i <= n; i++) {
cin >> a[i];
a[i] = a[i] + a[i - 1]; //a[0]的值是0,不影响结果
}
//多次区间计算,求最小值
for (int i = m; i <= n; i++) {
s = a[i] - a[i - m];
if (minV > s) minV = s;
}
cout << minV;
return 0;
}