Pagini recente » Cod sursa (job #3248439) | Cod sursa (job #54949) | Cod sursa (job #1305553) | Cod sursa (job #1576516) | Cod sursa (job #2710853)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("ferma.in");
ofstream fout("ferma.out");
const int NMAX = 1e4 + 4;
const int KMAX = 1e3 + 3;
int N, K, a[NMAX], dp[KMAX][NMAX], sum[NMAX], ans;
void max_self(int &a, int b) {
a = max(a, b);
}
int main() {
fin >> N >> K;
for(int i = 1; i <= N; ++i) {
fin >> a[i];
sum[i] = sum[i - 1] + a[i];
}
// intai nu tinem cont de circularitatea sirului
// dp[k][i] - valoarea maxima ce o pot obine din k secvente formate cu primele i numere din sir
// dp[k][i] = max(dp[k][i - 1], (dp[k - 1][j] - sum[j] + sum[i] | j < i)).
// traducere: ori las la fel cele k secvente(ca in primele i - 1 numere)
// ori incerc sa creez una noua pe care sa o adaug la alte k - 1
// ne trebuie astfel la un pas valoarea maxima (dp[k - 1][j] - sum[j] | j < i)
// avand dp[k - 1] deja caclculat, aceasta valoare se poate afla pe parcursul parcurgerii cu indicele j
for(int i = 1; i <= K; ++i) {
int val = dp[i - 1][i - 1] - sum[i - 1];
for(int j = i; j <= N; ++j) {
dp[i][j] = max(dp[i][j - 1], val + sum[j]);
max_self(val, dp[i - 1][j] - sum[j]);
}
}
max_self(ans, dp[K][N]);
// acum trebuie sa tratam si secventele obtinute pentru ca sirul e circular
for(int i = 1; i <= N; ++i)
dp[1][i] = max(dp[1][i - 1], sum[i]);
for(int i = 2; i <= K; ++i) {
int val = 0;
dp[i][1] = a[1]; // obligam practic secventele sa-l contina pe 1
for(int j = 2; j <= N; ++j) {
dp[i][j] = max(dp[i][j - 1], val + sum[j]);
val = max(val, dp[i - 1][j] - sum[j]);
}
}
for(int i = K; i <= N; ++i)
max_self(ans, dp[K][i] + sum[N] - sum[i]); // adaugam bucata de la i la N pentru a obtine secventa circulara
fout << ans << '\n';
}