George and Job - 每天一把CF - 20201026

蓝桥杯从小白开始三个月拿省一???就这???
鸽了两天
dp 467C 1700

题目

原题链接:https://codeforces.com/problemset/problem/467/C

在这里插入图片描述

思路

题目大意:从n个数字的序列中选取k个长度为m的子序列求其和,并且要求这些子序列不能够有重叠,求出最大的和。

思路:针对某个子序列选或不选。

dp[i][j] - 当前选第i个子序列,末尾为j的子序列是否要选择

代码实现

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

typedef long long ll;

const int MAX = 5e3 + 5;

ll n, m, k;
ll a[MAX], dp[2][MAX];
ll ans;

int main() {

	while (cin >> n >> m >> k) {
		memset(dp, 0, sizeof(dp));
		a[0] = ans = 0;

		for (int i = 1; i <= n; i++)
		{
			cin >> a[i];
			a[i] += a[i - 1];
		}

		for (int i = 1; i <= k; i++)
		{
			for (int j = m; j <= n; j++) {
				dp[i & 1][j] = max(dp[i & 1][j - 1], dp[(i - 1) & 1][j - m] + a[j] - a[j - m]);
			}
		}

		for (int i = m; i <= n; i++) ans = max(ans, dp[k & 1][i]);
		cout << ans << endl;
	}

	return 0;;
}
©️2020 CSDN 皮肤主题: 黑客帝国 设计师:上身试试 返回首页