一:原题描述
输入格式
第一行包含三个整数 n,m,k。
第二行包含 n个整数 a1,a2,…,an
输出格式
一个整数,表示 sum的最大可能值。
数据范围
前 66 个测试点满足 1≤m×k≤n≤20
所有测试点满足 1≤m×k≤n≤5000, 1≤m×k≤n≤5000,0≤ai≤10^9。
输入样例1:
5 2 1
1 2 3 4 5
输出样例1:
9
输入样例2:
7 1 3
2 10 7 18 5 33 0
输出样例2:
61
二:解题思路
首先上动态规划五部曲:
1.dp[i][j]表示从a[0],a[1]...a[i]即从前i个数中选,取j个长度为m的区间,所选取的元素的总和是最大值。
2.递推公式:dp[i][j] = max(dp[i-1][j], dp[i - m][j-1] + sum[i] - sum[i-m]);
3.初始化:dp全部初始为0就行。
4.确定遍历顺序:从前往后。
5.打印数组检验。
三:AC的源码
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main()
{
int n, m, k;
cin >> n >> m >> k;
vector<int> a(n+1, 0);
vector<long long > sum(n + 1, 0);
for (int i = 1; i <= n; i++)
{
cin >> a[i];
sum[i] =sum[i-1]+a[i];//前序和
}
vector<vector<long long>> dp(n + 1, vector<long long >(k+1,0));
for(int i=1;i<=n;i++)
for (int j = 1; j <= k; j++)
{
if (i - m + 1 >= 1&&i>=j*m)//右端点为i,则左端点(i-m+1)从1开始
{
dp[i][j] = max(dp[i-1][j], dp[i - m][j-1] + sum[i] - sum[i-m]);
}
}
cout << dp[n][k];
return 0;
}