C. George and Job time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output
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.
Sample test(s) input
5 2 1
1 2 3 4 5
output
9
input
7 1 3
2 10 7 18 5 33 0
output
61
題目大意:
給出一個數字序列,要求找出k個m長度不相交的區間,且區間數字之和最大
解法:
經典的動态規劃。狀态轉移方程:f[i][j] = max(f[i][j-1], f[i-1][j-m]+sum[j]-sum[j-m]) 其中i代表有多少段(1 <= i <= k),j表示第幾個數字。
注意要使用long long,可以用滾動數組優化記憶體
代碼:
#include <cstdio>
#define LL long long
LL n, m, k, f[2][5010], sum[5010];
LL max(LL a, LL b) {
if (a > b) return a;
return b;
}
void init() {
scanf("%I64d%I64d%I64d", &n, &m, &k);
for (int i = 1; i <= n; i++) {
scanf("%I64d", &sum[i]);
sum[i] += sum[i-1];
}
}
void solve() {
LL ans=0;
for (int i = 1; i <= k; i++)
for (int j = m; j <= n; j++)
f[i&1][j] = max(f[i&1][j-1] ,f[(i-1)&1][j-m]+sum[j]-sum[j-m]);
for (int j = 1; j <= n; j++)
ans = max(ans, f[k&1][j]);
printf("%I64d\n", ans);
}
int main() {
init();
solve();
}