Cod sursa(job #257028)

Utilizator Sorin_IonutBYSorynyos Sorin_Ionut Data 12 februarie 2009 18:26:50
Problema Subsir crescator maximal Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.09 kb
#include<stdio.h>

#define IN "scmax.in"
#define OUT "scmax.out"
#define nmax (100*1000+1)

FILE *fin=fopen(IN,"r");
FILE *fout=fopen(OUT,"w");

int v[nmax]; //vectorul cu sirul
int a[nmax]; //a[i]-pozitia elementului din v[], ce are o lungime a subsirului ce se termina in v[a[i]] egala cu i.
int b[nmax]; //pozitia elementului precedent in subsir crecator de lungime maxima
int l; //lungimea maxima gasita
int n; //lungimea sirului

void citire(int v[nmax], int *n);
void afisare(int p);
int cbin(int i);
void dinamica();

int main()
{
 citire(v,&n); //citim sirul
  fclose(fin);
  
 dinamica(); //facem dinamica

 fprintf(fout,"%d\n",l); //afisem lungimea
 afisare(a[l]); //afisem susirul incepand de la elementul de lungime maxima (pt k il afisem in psotordine)
  fclose(fout);

return 0;
}

void citire(int v[nmax], int *n)
{
 int i;
 
 fscanf(fin,"%d\n",n);
 
 for(i=1;i<=*n;i++)
  fscanf(fin,"%d",&v[i]);
}

//pozitia ce trebuie afisata
void afisare(int p)
{
 if(b[p])
  afisare(b[p]); //ii afisez intai tatal
 fprintf(fout,"%d ",v[p]); //il afisez pe el
}

//returnam lungimea maxima pe care o poate continua elementul de la pozitia i
int cbin(int i)
{
 int m,p=1,q=l;
 int lm=0; //lungimea maxima ce o poate continua
 
 while(p<=q) //nu am terminat de cautat
 {
  m=(p+q)/2; //pozitia din mijloc
  if(v[a[m]]<v[i]) //elementul este mai mic
  {
   lm=m; //lungimea maxima:P
   p=m+1; //cautam in partea dreapta
  }
  else q=m-1; //este prea mare...restrictionam cautarea in partea stanga
 }
 return lm; //returnam lungimea maxima ce o poate continua elementul de la pozitia i
}

//rezolvarea dinamica
void dinamica()
{
 int i,j;
 a[l=1]=1; //ungimea maxima este 1, si ultimul element este defapt primul element din sir
 
 for(i=2;i<=n;i++) //trecem pe la fiecare element
 {
  j=cbin(i); //primim lungimea maxima ce o poate continua elementul de la pozitia i
  //salvam la lungime daca avem un element mai mic
  if(!a[j+1])
  {
   a[j+1]=i;
   l++;
  }
  else
   if(v[a[j+1]]>v[i])
    a[j+1]=i;
		
  b[i]=a[j]; //ii salvam tatal
 }
}