Problem Description 题目链接
The description of this problem is very short. Now give you a string(length N), and ask you the max sum of the substring which the length can't small than M.
Input
The first line is one integer T(T≤20) indicates the number of the test cases. Then for every case, the first line is two integer N(1≤N≤1000000) and M(1≤M≤N).
Then one line contains N integer indicate the number. All the number is between -10000 and 10000.
Output
Output one line with an integer.
Sample Input
2
5
1 1 -2 -2 -2 1
5
2 1 -2 -2 -2 1
Sample Output
1
-1
#include <iostream> #include <algorithm> using namespace std; typedef long long LL; const int MAX = 1000005; /* 思路:最长递增子序列,只不过有个数限制至少m个,所以转移方程有点变化 sum[i]表示前缀和 dp[i]表示i所在的最长序列和 转移方程为 dp[i]=max(dp[i-1]+nums[i],sum[i]-sum[i-m])
后面还有一个加速版 */ int nums[MAX]; LL sum[MAX]; LL dp[MAX]; int main() { int n, t, m; scanf("%d", &t); sum[0] = 0; while (t--) { scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) { scanf("%d", &nums[i]); sum[i] = sum[i - 1] + nums[i]; } LL maxNum = sum[m]; dp[m] = maxNum; for (int i = m + 1; i <= n; i++) { dp[i] = max(dp[i - 1] + nums[i], sum[i] - sum[i - m]); if (maxNum < dp[i]) maxNum = dp[i]; } printf("%I64d ", maxNum); } }
省内存版:
#include <iostream> #include <algorithm> using namespace std; /* 迭代变量缩小内存 */ typedef long long LL; int nums[1000005]; int main() { int n, t, m; scanf("%d", &t); while (t--) { scanf("%d%d", &n, &m); LL lastSum = 0, preSum = 0; for (int i = 1; i <= m; i++) { scanf("%d", &nums[i]); lastSum += nums[i]; } LL maxNum = lastSum, temp = lastSum; for (int i = m + 1; i <= n; i++) { scanf("%d", &nums[i]); lastSum += nums[i]; preSum += nums[i - m]; temp = max(temp + nums[i], lastSum - preSum); if (maxNum < temp) maxNum = temp; } printf("%I64d ", maxNum); } }