Cod sursa(job #1335652)

Utilizator mirceadinoMircea Popoveniuc mirceadino Data 5 februarie 2015 19:50:30
Problema Euro Scor 100
Compilator cpp Status done
Runda Lista lui wefgef Marime 2.69 kb
/*

Let’s examine an O(N*sqrt(T)) solution (which is not so obvious). The first step is to “compress” the N values of the sequence into several contiguous intervals. The first interval contains the first K elements of the sequence, having the following property: K is N, or the sum of the first K elements is less than zero, but the sum of the first J elements is at least 0 (for any 1<=J<K). The next interval is obtained the same way, considering only the remaining N-K elements. This way, we split the subsequence into M “compressed” intervals. We can now use DP on the sequence of “compressed” intervals, the same way as for the original subsequence. This is, indeed, an improvement, as M is at most N, but the time complexity of the algorithm may still be O(N2) in the worst case. The catch is that, in order to find the optimal solution for the sequence ending with the ith interval, it is only necessary to look at the solutions for the previous sqrt(T)+1 intervals. This leads to an O(N*sqrt(T)) algorithm.

(din solutia oficiala)

*/

#include<algorithm>
#include<bitset>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<deque>
#include<fstream>
#include<iomanip>
#include<iostream>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<unordered_map>
#include<unordered_set>
#include<utility>
#include<vector>

using namespace std;

#define dbg(x) (cout<<#x<<" = "<<(x)<<'\n')
#ifdef HOME
const string inputFile = "input.txt";
const string outputFile = "output.txt";
#else
const string problemName = "euro";
const string inputFile = problemName + ".in";
const string outputFile = problemName + ".out";
#endif

typedef long long int lld;
typedef pair<int, int> PII;
typedef pair<int, lld> PIL;
typedef pair<lld, int> PLI;
typedef pair<lld, lld> PLL;

const int INF = (1LL << 31) - 1;
const lld LINF = (1LL << 60) - 1;
const int dx[] = {1, 0, -1, 0, 1, -1, 1, -1};
const int dy[] = {0, 1, 0, -1, 1, -1, -1, 1};
const int NMAX = 34567 + 5;

int N, T, M;
int S[NMAX];
lld DP[NMAX];
int V[NMAX];

int main() {
    int i, j, x;

#ifndef ONLINE_JUDGE
    freopen(inputFile.c_str(), "r", stdin);
    freopen(outputFile.c_str(), "w", stdout);
#endif

    scanf("%d%d", &N, &T);

    for(i = 1; i <= N; i++) {
        scanf("%d", &x);
        S[i] = S[i - 1] + x;
    }

    for(i = j = 1; i <= N; i++)
        if(S[i] - S[j - 1] < 0) {
            V[++M] = i;
            j = i + 1;
        }

    if(j <= N)
        V[++M] = N;

    for(i = 1; i <= M; i++) {
        DP[i] = -LINF;
        for(j = max((int)(i - sqrt(T) - 2), 1); j <= i; j++)
            DP[i] = max(DP[i], DP[j - 1] + (S[V[i]] - S[V[j - 1]]) * 1LL * V[i] - T);
    }

    printf("%lld\n", DP[M]);

    return 0;
}