Mai intai trebuie sa te autentifici.
Cod sursa(job #736079)
Utilizator | Data | 17 aprilie 2012 19:33:05 | |
---|---|---|---|
Problema | Transport | Scor | 100 |
Compilator | cpp | Status | done |
Runda | Arhiva de probleme | Marime | 1.49 kb |
#include <iostream>
#include <fstream>
using namespace std;
int main() {
ifstream f("transport.in");
ofstream g("transport.out");
int n, k, v[16005], i, s, stotal=0, vmax=0, begin, end, mid, pasi;
f>>n>>k;
for(i=n; i>=1; i--) {
f>>v[i];
stotal+=v[i];
if(v[i]>vmax) vmax=v[i];
}
v[0]=0;
//IDEE: caut binar in intervalul [Vmax, Stotal] cea mai mica valoare pentru care pot incarca saltelele
//folosind maxim k transporturi
begin = vmax-1; //volumul camionului >= volumul celei mai mari saltele (daca o incarca doar pe cea mai mare)
end = stotal+1; //volumul camionului <= suma tuturor volumelor saltelelor (daca le incarca pe toate)
while(end-begin>1) {
mid = begin+(end-begin)/2; //mid ii volumul camionului
pasi = 0;
i = n; //incep din varful stivei
s = 0;
while(i>=1) { //iau saltelele de la varful stivei spre baza
s=0; //camion gol
while(s+v[i] <= mid && i>=1) {
s+=v[i]; //epuizez toate saltele care incap in camion la un transport
i--;
}
pasi++; //contorizez transportul
if(pasi>k) i=0; //un pic de optimizare, ma opresc cand am depasit limita k, chiar daca nu am terminat saltelele
}
if(pasi>k) begin = mid; //caut o valoare mai mare (jumatatea dreapta a intervalului)
else end = mid; //caut o valoare mai mica (jumatatea stanga a intervalului)
}
//greseala pentru care luam 80: tipaream "mid" in loc de "end"
g<<end<<"\n";
f.close();
g.close();
return 0;
}