Pagini recente » Cod sursa (job #592593) | Cod sursa (job #1470122) | Cod sursa (job #2251931) | Cod sursa (job #1804350) | Cod sursa (job #1712955)
#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;
}