【动态规划】CodeForce 1197D Yet Another Subarray Problem

这段时间要沉迷刷题一段时间了,就让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 
#include 
#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;
}

如果有问题,欢迎大家指正!!!

你可能感兴趣的:(CodeForce)