Cod sursa(job #2032337)

Utilizator stefzahZaharia Stefan Tudor stefzah Data 4 octombrie 2017 20:36:15
Problema Ferma Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.63 kb
#include <fstream>
#include <cstring>

using namespace std;

const int KMAX = 1000 + 5;
const int NMAX = 10000 + 5;

int N;
int v[NMAX];

int dp1[2][NMAX]; //dp1[i][j] = daca iau i subsecvente si ultima se termina pe pozitia j
int dp2[2][NMAX]; //dp2[i][j] = daca iau i subsecvente si ultima se termina pe o pozitie <= j

int main()
{
    ifstream cin("ferma.in");
    ofstream cout("ferma.out");

    //Read
    int K = 0;
    cin >> N >> K;

    for (int i = 1; i <= N; ++ i)
        cin >> v[i];

    //Solve without circularity
    bool h = 1;
    for (int i = 1; i <= K; ++ i, h ^= 1) {
        for (int j = 1; j <= N; ++ j) {
            if (j >= 2)
                dp1[h][j] = v[j] + max(dp1[h][j - 1], dp2[h ^ 1][j - 2]);
            else
                dp1[h][j] = v[j] + dp1[h][j - 1];

            dp2[h][j] = max(dp2[h][j - 1], dp1[h][j]);
        }
    }

    int ans = dp2[h ^ 1][N];

    //Force first element to be taken
    memset(dp1, 0, sizeof(dp1));
    memset(dp2, 0, sizeof(dp2));

    h = 1;
    for (int j = 1; j <= N; ++ j) {
        dp1[h][j] = v[j] + dp1[h][j - 1];
        dp2[h][j] = max(dp2[h][j - 1], dp1[h][j]);
    }

    h = 0;
    for (int i = 2; i <= K; ++ i, h ^= 1) {
        for (int j = 1; j <= N; ++ j) {
            dp1[h][j] = v[j] + max(dp1[h][j - 1], dp2[h ^ 1][j - 2]);
            dp2[h][j] = max(dp2[h][j - 1], dp1[h][j]);
        }
    }

    //Tackle circularity
    int sum = 0;
    for (int i = N; i > 1; -- i) {
        sum += v[i];
        ans = max(ans, dp2[h ^ 1][i - 1] + sum);
    }

    //Print
    cout << ans << '\n';
    return 0;
}