Pagini recente » Cod sursa (job #260481) | Cod sursa (job #2372599) | Cod sursa (job #2382454) | Cod sursa (job #3262036) | Cod sursa (job #822299)
Cod sursa(job #822299)
#include <cstdio>
FILE* in;
FILE* out;
template<class T>
int binary_search(T* v, int *index, int a, int b, const T& value) {
if(a == b) {
return (!(v[index[a]] < value))?(a):(a + 1);
}
int mid = (a + b) / 2;
if(v[index[mid]] < value) {
return binary_search(v, index, mid + 1, b, value);
}
else {
return binary_search(v, index, a, mid, value);
}
}
void afis(int *v, int s, int n, const char mess[]) {
fprintf(stderr, "%s", mess);
for(int i = s; i < n + s; ++i)
fprintf(stderr, "%d ", v[i]);
fprintf(stderr, "\n");
}
/*
* Functia care determina un subsir crescator maximal dintr-un vector
*/
int* scmax(int *v, int &n) {
int j;
/* Alocarea memoriei */
/* best[i] = lungimea subsirului crescator maximal ce se termina pe poz i */
int *best = new int[n + 1];
/* m[i] = indicele celui mai mic numar din v care are lungimea i */
int *m = new int[n + 1];
/* vector de predecesori */
int *prev = new int[n + 1];
/* jmax este pozitia din v unde se termina cel mai lung subsir crescator */
int jmax = 0;
/* initializam vectorii ajutatori */
best[1] = 1;
v[0] = 0;
/* imax e lungimea lui m completat pana la un anumit pas */
int imax = 0;
for(int i = 1; i <= n; ++i) {
/* cautam intervalul minim in care se afla v[i] O(log(n))*/
j = binary_search(v, m, 0, imax, v[i]);
/* introducem lungimea scm ce se termina pe pozitia i in best[i]*/
best[i] = j;
/* memoram lungimea maxima dintre lungimile subsirurilor crescatoare */
if(best[i] > best[jmax])
jmax = i;
/* retinem elementul anterior unui element dintr-un subsir crescator */
prev[i] = m[j - 1];
/* punem indicele minimului in pozitia j (stim v[i] < v[m[j]])*/
m[j] = i;
/* retinem lungimea lui m (pentru cautarea binara) */
if(j > imax)
imax++;
}
fprintf(out, "%d\n", imax);
/* generam rezultatul ajutandu-ne de vectorul de predecesori */
int *rez = new int[imax + 1];
j = 0;
rez[j++] = jmax;
for(int i = jmax; prev[i]; i = prev[i]) {
rez[j] = prev[i];
j++;
}
/* Afisare */
for(int i = j - 1; i >= 0; --i)
fprintf(out, "%d ", v[rez[i]]);
fprintf(out, "\n");
/* Dezalocare */
delete best;
delete m;
delete prev;
delete rez;
}
int main(int argc, char **argv) {
argc--;
argv++;
//in = fopen(argv[0], "r");
//out = fopen(argv[1], "w");
in = fopen("scmax.in", "r");
out = fopen("scmax.out", "w");
int n;
fscanf(in, "%d", &n);
int *price = new int[n + 1];
for(int i = 1; i <= n; ++i) {
fscanf(in, "%d", price + i);
}
scmax(price, n);
delete price;
fclose(in);
fclose(out);
return 0;
}