Cod sursa(job #772378)
#include <iostream>
#include <fstream>
using namespace std;
ifstream f("ferma.in");
ofstream g("ferma.out");
#define nmax 10005
#define Kmax 1005
int n, k, a[2*nmax], dp[2*nmax][Kmax];
void citeste(){
f >> n >> k;
for(int i=1; i<=n; i++) f >> a[i];
for(int i=n+1; i<=2*n-1; i++) a[i] = a[i-n];//dublez vectorul pentru a fi circular
}
int suma(int i, int j){
int s = 0;
for(int x=i; x<=j; x++) s += a[x];
return s;
}
void rezolva(){
//dp[i][j] = numarul maxim de gaini din primele i sectoare avand j treceri
int rez = 0;
for(int poz=1; poz<=n; poz++){//iau fiecare pozitie ca si pozitie de inceput
for(int w=0; w<=2*n; w++){
for(int j=1; j<=k; j++) dp[w][j] = 0;
}
dp[poz][1] = max(0, a[poz]);
for(int i=poz+1; i<=n+poz-1; i++){
for(int j=1; j<=k; j++){
dp[i][j] = dp[i-1][j];
for(int kk=i; kk>=poz+1; kk--){
dp[i][j] = max(dp[i][j], suma(kk,i) + dp[kk-1][j-1]);
}
}
}
int Max = 0;
Max = dp[poz+n-1][k];
if (rez < Max ) rez = Max;
}
g << rez << "\n";
}
int main(){
citeste();
rezolva();
f.close();
g.close();
return 0;
}