题干:
The new ITone 6 has been released recently and George got really keen to buy it. Unfortunately, he didn't have enough money, so George was going to work as a programmer. Now he faced the following problem at the work.
Given a sequence of n integers p1, p2, ..., pn. You are to choose k pairs of integers:
[l1, r1], [l2, r2], ..., [lk, rk] (1 ≤ l1 ≤ r1 < l2 ≤ r2 < ... < lk ≤ rk ≤ n; ri - li + 1 = m),
in such a way that the value of sum is maximal possible. Help George to cope with the task.
Input
The first line contains three integers n, m and k (1 ≤ (m × k) ≤ n ≤ 5000). The second line contains n integers p1, p2, ..., pn (0 ≤ pi ≤ 109).
Output
Print an integer in a single line — the maximum possible value of sum.
Examples
Input
5 2 1
1 2 3 4 5
Output
9
Input
7 1 3
2 10 7 18 5 33 0
Output
61
题目大意:
给定n,m,k。求k个子段,每一段的长度是m,且每一段均要求不相交。求选中段的最大和。
解题报告:
直接dp[i][j]代表前i个数,分成j个子段,的最大和,然后转移即可。
也可以定义成dp[i][j]代表以第i个数为结尾,分成j个子段的最大和,这样的话需要枚举上一个断点,不过可以用一个数组预处理前缀最大值,所以复杂度是一样的,都可解。
AC代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define FF first
#define SS second
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
typedef pair<int,int> PII;
const int MAX = 2e5 + 5;
ll a[MAX],sum[MAX],dp[5005][5005],n,m,k;
int main()
{cin>>n>>m>>k;for(int i = 1; i<=n; i++) scanf("%lld",a+i);for(int i = 1; i<=n; i++) sum[i] = sum[i-1] + a[i];for(int i = m; i<=n; i++) {for(int j = 1; j<=k; j++) {dp[i][j] = max(dp[i-1][j],dp[i-m][j-1] + sum[i]-sum[i-m]);}}printf("%lld\n",dp[n][k]);return 0 ;
}