Pagini recente » Cod sursa (job #2418503) | Cod sursa (job #2952206) | Cod sursa (job #1887265) | Cod sursa (job #662848) | Cod sursa (job #2764937)
#include <fstream>
using namespace std;
int n, k;
int a[10001];
int Max = 0; // consideram ca rezultatul nu poate fi mai mic de 0 (scrie in enunt)
int dp[1001][10001];
int sum[10001];
void read() {
int i;
ifstream f("ferma.in");
f >> n >> k;
for (i = 1; i <= n; i++)
f >> a[i];
f.close();
}
void solve() {
int val, i, j;
// sume partiale pe vectorul a
for (i = 1; i <= n; i++)
sum[i] = sum[i - 1] + a[i];
// fara circularitate
// Formula : dp[i][j] = max(dp[i][j - 1], dp[i - 1][nr] - sum[nr] + sum[j]) -> o tratam inteligent in O(k * n) nu O(k * n^2)
for (i = 1; i <= k; i++) {
val = dp[i - 1][i - 1] - sum[i - 1];
for (j = i; j <= n; j++) {
dp[i][j] = max(dp[i][j - 1], val + sum[j]);
val = max(val, dp[i - 1][j] - sum[j]);
}
}
Max = max(Max, dp[k][n]);
// tratam circularitatea
// pentru k = 1 -> tratam cazul in care consideram suma primelor i numere sau nu
for (i = 1; i <= n; i++)
dp[1][i] = max(dp[1][i - 1], sum[i]);
// pentru celelalte cazuri fortam ca secventa sa contina si a[1] daca se poate (pentru circularitate)
for (i = 2; i <= k; i++) {
dp[i][1] = a[1];
val = 0;
for (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]);
}
}
// in final comparam rezultatul in care putem avea circularitate cu cel fara de mai devreme
for (i = k; i <= n; i++)
Max = max(Max, dp[k][i] + sum[n] - sum[i]); // consideram si cazul in care ultima secventa se lipeste de rezultatul fara circularitate
}
void output() {
ofstream g("ferma.out");
g << Max;
g.close();
}
int main() {
read();
solve();
output();
return 0;
}