Cod sursa(job #2201935)

Utilizator RaduIonescuRadu Ionescu RaduIonescu Data 6 mai 2018 17:24:36
Problema Carnati Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.41 kb
#include <algorithm>
#include <iostream>
#include <fstream>
#include <cassert>
#include <ctime>

using namespace std;

ofstream out ("carnati.out");

const int N = 2005;

struct client{
    int ora;
    int bani;
};

client vcl[2007];

bool comp(client a,client b)
{
    return (a.ora<b.ora);
}

int sumax (int a[])
{
    int s,smax,i;

    s=smax=a[0];

    for (i=1;i<1501;++i)
    {
        if (s<0) s=a[i];

        else s+=a[i];

        if (s>smax) smax=s;
    }

    return smax;
}

int profit(int n, int cost, client vcl[], int index)
{
    long long costactual=vcl[index].bani,i,j;
    long long intretinere,venit=0;
    long long bestProfitDreapta,bestProfitStanga;
    bestProfitDreapta = bestProfitStanga = -1500000000001LL;

    for (i=index+1;i<n;++i)
    {
        intretinere=(vcl[i].ora-vcl[index].ora)*cost;

        if (vcl[i].bani>=costactual) venit+=costactual;

        long long profit=venit-intretinere;
        //cout<<"  ora="<<vcl[i].ora<<", profit="<<profit<<"\n";
        bestProfitDreapta = max(bestProfitDreapta, profit);
    }

    venit=0;

    for (i=index-1;i>-1;--i)
    {
        intretinere=-((vcl[i].ora-vcl[index].ora)*cost);

        if (vcl[i].bani>=costactual) venit+=costactual;

        long long profit=venit-intretinere;
        bestProfitStanga = max(bestProfitStanga, profit);
    }

    long long profitFinal = vcl[index].bani - cost;
    if(bestProfitDreapta > 0)
        profitFinal += bestProfitDreapta;
    if(bestProfitStanga > 0)
        profitFinal += bestProfitStanga;

    //cout<<"index = "<<index<<", bani = "<<vcl[index].bani<<", cost = "<<cost<<"\n"; cout<<"profit initial = "<<vcl[index].bani - cost<<"\n"; cout<<"bestProfitStanga = "<<bestProfitStanga<<"\n"; cout<<"bestProfitDreapta = "<<bestProfitDreapta<<"\n";

    return profitFinal;
}

int solve_1(int n, int cost, client vcl[]){
    int profitMax = 0;
    for(int i=0; i<n; ++i)
        profitMax = max(profitMax, profit(n, cost, vcl, i));

    return profitMax;
}

int solve_2(int n, int cost, client vcl[]){
    int i,j;

    int sumpartz[N];
    int MAXIM = 0;

    for (i=0;i<n;++i)
    {
        int pretcrt=vcl[i].bani;

        for(j=0; j<=1501; ++j)
            sumpartz[j] = -cost;

        for (j=0;j<n;++j)
            if (pretcrt<=vcl[j].bani)
                sumpartz[vcl[j].ora]+=pretcrt;

        int s = sumax(sumpartz);
        MAXIM=max(MAXIM,s);
    }

    return MAXIM;
}

void genereaza_test()
{
    ofstream f("carnati.in");

    int n = 1 + rand()%2000;
    int cost = 1 + (rand()*rand())%1000000;

    f<<n<<" "<<cost<<"\n";

    for(int i=0; i<n; ++i){
        f<<(0 + rand()%1501)<<" "<<(0 + rand()%1000001)<<"\n";
    }
    f.close();
}

int main()
{
    srand(time(NULL));
    int n,cost, timp[N], pret[N];
    int i,j;

    const bool DEBUG = 0;
    const int NR_TESTE = 1;

    for(int test = 0; test < NR_TESTE; ++test){
        if(DEBUG) genereaza_test();

        ifstream in ("carnati.in");
        in>>n>>cost;
         for (i=0;i<n;++i)
            in>>vcl[i].ora>>vcl[i].bani;

        sort (vcl,vcl+n,comp);

        int sol_1 = solve_1(n, cost, vcl);
        int sol_2 = solve_2(n, cost, vcl);

        //cout<<"Sol 1 = "<<sol_1<<"\n"; cout<<"Sol 2 = "<<sol_2<<"\n";
        in.close();
        if(DEBUG) assert(sol_1 == sol_2);

        out<<sol_2;
    }

    return 0;
}