Cod sursa(job #843488)

Utilizator mihai995mihai995 mihai995 Data 27 decembrie 2012 23:29:52
Problema Euro Scor 45
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.92 kb
#include <fstream>
#include <iostream>
using namespace std;

const int N = 35001;

struct Smen{
    struct Nod{
        long long a, b;
        int i;

        Nod(){
            i = 0;
        }

        Nod(int _a, int _b, int _i){
            a = _a;
            b = _b;
            i = _i;
        }

        int eval(int t){
            return a * t + b;
        }

        bool surpass(Nod x, Nod y){
            return x.a * b + a * y.b + y.a * x.b >= x.b * a + b * y.a + y.b * x.a;
        }
    };

    Nod v[N];
    int size;

    void push(int a, int b, int i){
        Nod x = Nod(a, b, i);

        while (size > 1 && v[size - 1].surpass(v[size], x))
            size--;

        v[++size] = x;
    }

    void reset(){
        size = 0;
    }

    int front(int timp){
        while (size > 1 && v[size].eval(timp) < v[size - 1].eval(timp))
            size--;

        return v[size].i;
    }
};

long long S[N], v[N], T;
Smen D;
int n;

ifstream in("euro.in");
ofstream out("euro.out");

template<class T>
void print(T v[]){
    for (int i = 1 ; i <= n ; i++)
        cout << v[i] << " ";

    cout << "\n";
}

long long compute(){
    D.reset();

    D.push(n, 0, n + 1);

    for (int i = n ; i ; i--){
        int j = D.front(S[i]);

        v[i] = v[j] + (j - 1) * (S[i] - S[j]) - T;

        D.push(i - 1, v[i] - S[i] * (i - 1), i);
    }

    //print(v);

    return v[1];
}

long long brute(){
    for (int i = n ; i ; i--){
        v[i] = n * S[i] - T;

        for (int j = i + 1 ; j <= n ; j++)
            v[i] = max(v[i], v[j] + (j - 1) * (S[i] - S[j]) - T);
    }

    print(v);

    return v[1];
}

int main(){
    in >> n >> T;

    for (int i = 1 ; i <= n ; i++)
        in >> S[i];

    for (int i = n - 1 ; i ; i--)
        S[i] += S[i + 1];

    //out << brute() << "\n";
    out << compute() << "\n";

    return 0;
}