Cod sursa(job #1712955)

Utilizator Vertex10Alexandru Pokharel Vertex10 Data 4 iunie 2016 12:55:50
Problema Transport Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.65 kb
#include <fstream>

using namespace std;

ifstream f("transport.in");
ofstream g("transport.out");
int n, k, v[16001], minim, suma_volume;

//rezolvare: caut binar capacitatea camionului in intervalul [saltea volum maxim; suma volume saltele]
//si verific in O(N) pentru o capacitate X (preselectata prin caut bin) daca se poate efectua transpotrul
//in cel mult k drumuri (cf cerintei). Daca numarul de transporturi determinat X este mai mic sau egal cu K,
//atunci se poate incerca o capacitate mai mica; in caz contrar, se va incerca o capacitate mai mare.
///O(N*(N*logN)) = O(N^2*logN)

bool verif (int x) //verif daca pot ef. max k drumuri cu o capacitate a camionului data (X)
{
    int tr = 0; //nr drumuri curente
    for (int i=1, vol=0; i<=n && tr <= k; ++i, vol = 0) //cat timp nu fac mai mult de k drumuri, solutia e potential buna
    {
        while (vol + v[i] <= x && i<=n) //cat timp am loc sa adaug inca o saltea in camion
            vol += v[i], ++i;
        --i;
        ++tr;
    }
    if (tr <= k)
        return 1;
    return 0;
}

int cautBin ()
{
    int pas = 1 << 28; //worst case am k=1 (un singur drum) si limN saltele * toate de volum maxim (limN) => limN^2
    int x = suma_volume; //vol max pe care l-ar putea avea camionul
    while(pas)
    {
        if (x-pas >= minim && verif(x-pas))
            x-=pas;
        pas/=2;
    }
    return x;
}

int main()
{

    f >> n >> k;
    for (int i=1; i<=n; ++i)
    {
        f >> v[i];
        if (v[i] > minim) //"minim" e de fapt salteaua de vol maxim, cea mai mica valoare din interv pe care caut binar
            minim = v[i];
        suma_volume += v[i];
    }
    g << cautBin();

    return 0;
}