Pagini recente » Cod sursa (job #2466113) | Cod sursa (job #1342518) | Cod sursa (job #2292633) | Cod sursa (job #2737731) | Cod sursa (job #2128192)
#include "stdio.h"
#define MAX_N 100000
/* IO */
FILE *fin;
FILE *fout;
/* Problem Data */
int N;
int array[MAX_N];
int best[MAX_N];
int predecesor[MAX_N];
int max_index;
void read(void) {
fin = fopen("scmax.in", "r");
fscanf(fin, "%d", &N);
int i;
for (i = 0; i < N; i++) {
fscanf(fin, "%d", &array[i]);
}
fclose(fin);
}
/*void write(void) {
int subsequence[best[max_index]];
int index = max_index, nr = 0, i;
subsequence[nr++] = array[index];
while (predecesor[index] >= 0) {
subsequence[nr++] = array[predecesor[index]];
index = predecesor[index];
}
fout = fopen("scmax.out", "w");
fprintf(fout, "%d\n", best[max_index]);
for (i = nr - 1; i >= 0; i--) {
fprintf(fout, "%d ", subsequence[i]);
}
fclose(fout);
}*/
/* DP - simplu O(n^2) */
/*void solve(void) {
int i, j, max_best, global_best = 0;
best[0] = 1;
predecesor[0] = -1;
for (i = 1; i < N; i++) {
predecesor[i] = -1;
max_best = 0;
for (j = i - 1; j >= 0; j--) {
if (array[i] > array[j] && best[j] > max_best) {
max_best = best[j];
predecesor[i] = j;
}
}
best[i] = 1 + max_best;
if (best[i] > global_best) {
global_best = best[i];
max_index = i;
}
}
}*/
/* DP - folosind AIB - O(n*log n) */
#define zeros(x) ( (x ^ (x - 1)) & x )
int AIB[MAX_N+1];
/*int compute(int x) {
int i, ret = 0;
for (i = x; i > 0; i-= zeros(i))
ret += AIB[i];
return ret;
}*/
void add(int x, int q) {
int i;
for (i = x; i <= N; i += zeros(i)) {
AIB[i] += q;
}
}
int getMax(int x) {
int i, ret = 0;
for (i = x; i > 0; i -= zeros(i)) {
if (array[x] > array[i-1] && best[i] > ret) {
predecesor[x] = i-1;
ret = best[i];
}
}
return ret;
}
void solve2(void) {
int i, global_best = 0;
for (i = 0; i <= N; i++) {
AIB[i] = 0;
best[i] = 0;
}
add(1, 1);
best[1] = 1;
predecesor[0] = -1;
for (i = 1; i < N; i++) {
predecesor[i] = -1;
best[i+1] = 1 + getMax(i);
add(i+1, best[i+1]);
if (best[i+1] > global_best) {
global_best = best[i+1];
max_index = i;
}
}
}
void write2(void) {
int subsequence[best[max_index + 1]];
int index = max_index, nr = 0, i;
subsequence[nr++] = array[index];
while (predecesor[index] >= 0) {
subsequence[nr++] = array[predecesor[index]];
index = predecesor[index];
}
fout = fopen("scmax.out", "w");
fprintf(fout, "%d\n", best[max_index + 1]);
for (i = nr - 1; i >= 0; i--) {
fprintf(fout, "%d ", subsequence[i]);
}
fclose(fout);
}
int main(void) {
read();
solve2();
write2();
return 0;
}