Cod sursa(job #826317)

Utilizator BitOneSAlexandru BitOne Data 30 noiembrie 2012 16:47:43
Problema Avioane Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.02 kb
#include <queue>
#include <vector>
#include <cstdlib>
#include <fstream>
#include <iterator>
#include <algorithm>

using namespace std;
typedef pair<int, int> pr;

const int NMAX = 100011;

deque< pr > possibleMaxIdx;
vector< int > v, toSort, countApp;

inline int _max(int x, int y) {return x >= y ? x : y;}
int main()
{
   pr max;
   int N, M, profit, x, i, j, k;
   ifstream in("avioane.in");
   ofstream out("avioane.out");

   in >> N;

   profit = 0;
   switch(N) //basic cases
   {
      case 2 : in >> profit;

      case 1 : in >> x;
               profit+=x;
               out << profit << '\n';
               return EXIT_SUCCESS;

      default : copy(istream_iterator<int>(in), istream_iterator<int>(), back_inserter(toSort));
   }
   sort(toSort.begin(), toSort.end());
   for(i = 0; i < N; i = j) //determine the unique values
   {
      for(j = i + 1; j < N && toSort[i] == toSort[j]; ++j);
      countApp.push_back(j - i);
      v.push_back(toSort[i]);
   }

   switch(M = v.size()) //check again for basic cases
   {
       case 1 : out << v[0] * countApp[0] << '\n';                        return EXIT_SUCCESS;
       case 2 : out << (v[0] * countApp[0] + v[1] * countApp[1]) << '\n'; return EXIT_SUCCESS;
   }

   k = countApp[0] + countApp[1]; //the current index in the initial array
   profit = v[0] * countApp[0] + v[1] * (N - countApp[0]); //the "starting" profit

   max.first = v[0]; max.second = 0;
   for(i = 2; i < M; ++i)
   {
      while(false == possibleMaxIdx.empty())
      {
          pr x = possibleMaxIdx.front();
          if(x.first * (k - x.second) < v[i-1] * countApp[i-1]) possibleMaxIdx.pop_front();
          else break;
      }
      possibleMaxIdx.push_back(pr(v[i - 1], k - countApp[i-1]));
      pr x = possibleMaxIdx.front();
      if(max.first * (k - max.second) < x.first * (k - x.second ))
      {
         max = x;
         possibleMaxIdx.pop_front();
      }
      profit = _max(profit, max.first * (k - max.second) + v[i] * (N - k));
      k += countApp[i];
   }

   out << profit << '\n';
   return EXIT_SUCCESS;
}