这段时间要沉迷刷题一段时间了,就让CSDN陪我一起吧!
一、题目大意
题目的意思很简单,就是给定一个长度为n的数组,然后给定两个数m和k,用这两个数来定义子数组的cost,公式如下:
要求求解能得到的最大子数组cost。
二、题目思路以及AC代码
可能因为是大早上的,所以脑袋有点混沌,后来想了想感觉应该自己可以做出来的。
最开始想到的也是DP,但想复杂了,想成了二维DP暴力,然后用滚动数组优化空间,发现超时了,后来头脑混沌就去查了查题解,发现还是DP,只不过是一维的,思路也不是很难。
下面简单讲解一下,dp[i]表示以a[i]为结尾的所有可能子数组的最大cost值。这样的话,对应的递推的方式就是以m为单位,假如要求解dp[i],则需要由dp[i-m]推出,dp[i]要么是dp[i-m]加上a[i-m+1]到a[i]的和再减去k,对应的子数组就是i-m之前的某个数组加上a[i-m+1]到a[i],要么是a[i-m+1]到a[i]的一个某个新子数组,这个在我的代码中也有体现。
下面给出AC代码:
#include <iostream>
#include <algorithm>
#define MAXN 300010
using namespace std;
typedef long long ll;
int n, m, k;
ll a[MAXN];
ll dp[MAXN];
int main()
{
cin >> n >> m >> k;
for (int i = 1; i <= n; i++) {
cin >> a[i];
a[i] += a[i - 1];
}
ll ans = 0;
for (int i = 1; i <= n; i++) {
for (int j = i; j >= 1 && j >= i - m + 1; j--) {
dp[i] = max(a[i] - a[j - 1] - k, dp[i]);
}
if (i - m > 0) {
dp[i] = max(a[i] - a[i - m] + dp[i - m] - k, dp[i]);
}
ans = max(ans, dp[i]);
}
cout << ans << endl;
return 0;
}
如果有问题,欢迎大家指正!!!