Cod sursa(job #953718)

Utilizator claudiumihailClaudiu Mihail claudiumihail Data 27 mai 2013 07:59:06
Problema Avioane Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.31 kb
#include <fstream>
#include <iostream>
#include <vector>
#include <deque>
#include <iterator>
#include <algorithm>

#define MAXN 100001

using namespace std;

struct Profit
{
    Profit() :
        Position(0),
        Start(0),
        End(0)
    {}
    
    Profit(int p, int s, int e) :
        Position(p),
        Start(s),
        End(e)
    {}

    int Position;
    int Start;
    int End;
};

long long profits[MAXN];

int main()
{
    int n;
    vector<int> vCustomers;
    fstream fin("avioane.in", fstream::in);
    fstream fout("avioane.out", fstream::out);

    fin >> n;
    //cout << n << endl;

    istream_iterator<int> itIn(fin);
    copy_n(itIn, n, back_inserter(vCustomers));

    sort(vCustomers.begin(), vCustomers.end());

    /*ostream_iterator<int> itOut(cout, " ");
    copy_n(vCustomers.begin(), n, itOut);
    cout << endl << endl;*/

    deque<Profit> deq;
    deq.push_back(Profit(0, 0, n));
    
    profits[0] = vCustomers[0];

    double MaxProfit = vCustomers[0];
    int MinEnd = n;
    for (int i=1; i<n; ++i)
    {
        if (vCustomers[i] == vCustomers[i-1])
        {
            profits[i] = vCustomers[deq.front().Position] * (i - deq.front().Position + 1);
            continue;
        }

        //cout << "here " << floor(( (double) (i - deq.back().Position) * vCustomers[deq.back().Position]) / (vCustomers[i] - vCustomers[deq.back().Position])) << endl;
        while (!deq.empty() && i + floor( (double) (( i - deq.back().Position) * vCustomers[deq.back().Position])/ (vCustomers[i] - vCustomers[deq.back().Position])) <= deq.back().Start)
        {
            deq.pop_back();
        }
        
        int start = 0;
        if (!deq.empty())
        {
            start = floor(( (double) (i - deq.back().Position) * vCustomers[deq.back().Position]) / (vCustomers[i] - vCustomers[deq.back().Position]));
            deq.back().End = i + start;
        }
        
        MinEnd = min(MinEnd, i + start);

        deq.push_back(Profit(i, i + start, n));
        //cout << i << " " << start << " ";
        
        while (deq.front().Start < MinEnd && MinEnd == i)
        {
            deq.pop_front();
        }
        
        MinEnd = deq.front().End;
        
        MaxProfit = vCustomers[deq.front().Position] * (i - deq.front().Position + 1);
        //cout << deq.front().Position << " " << deq.front().End << " " << MaxProfit << endl;
        
        profits[i] = MaxProfit;
    }

    /*for (int i=0; i<n; ++i)
    {
        cout << profits[i] << " ";
    }
    cout << endl << endl;
    
    MaxProfit = 0;
    long long economyProfit = 0;

    for (int i=1; i<=n; ++i)
    {
        for (int j=i-1; j>=0; --j)
        {
            economyProfit = max(economyProfit, static_cast<long long>(vCustomers[j]) * (i - j));
        }
        cout << economyProfit << " ";
        
        MaxProfit = max(MaxProfit, economyProfit + static_cast<double>(vCustomers[i]) * (n - i));
    }
    cout << endl;

    cout << static_cast<long long>(MaxProfit) << "\n";*/
    
    MaxProfit = 0;
    for (int i=1; i<=n; ++i)
    {   
        MaxProfit = max(MaxProfit, profits[i-1] + static_cast<double>(vCustomers[i]) * (n - i));
    }

    fout << static_cast<long long>(MaxProfit) << "\n";

    return 0;
}