Cod sursa(job #87316)

Utilizator gigi_becaliGigi Becali gigi_becali Data 26 septembrie 2007 22:44:02
Problema Subsir 2 Scor 55
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.04 kb
#include <cstdio>
#define maxn 5001
#define oo 0x3f3f3f3f

int a[maxn], dp[maxn], t[maxn];
int Q[maxn], nq;
int n;
int last[maxn], first[maxn];

int main()
{
  freopen("subsir2.in","r",stdin);
  scanf("%d\n", &n);
  int i, j;
  for(i=1;i<=n;++i)scanf("%d ", a+i);

  first[1]=1;
  for(i=2;i<=n;++i)
    {
      int ok=1;
      for(j=1;j<i;++j)
	if(a[j]<=a[i]) {ok=0;break;}
      first[i]=ok; 
    }
  last[n]=1;
  for(i=n-1;i>=1;--i)
    {
      int ok=1;
      for(j=i+1;j<=n;++j)
	if(a[j]>=a[i]) { ok=0;break;}
      last[i]=ok;
    }

  dp[n]=1;
  int min, p, Dp;
  
  if(n<=500)
    {
      int k, ok;
      for(i=n-1;i>=1;--i)
	{
	  dp[i]=oo;
	  min=oo;
	for(j=i+1;j<=n;++j)
	    if(a[i]<=a[j])
	  {
	    ok=1;
	    for(k=i+1;k<j && ok;++k)
	      if(a[k]>=a[i] && a[k]<=a[j]) ok=0;
	    if(dp[j]==1 && last[j]==0) ok=0;
	    // if(last[j]==0) ok=0;
	    if(j==i+1) ok=1; 
	    if(ok)
	      {
		if(dp[i]>dp[j]+1){ dp[i]=dp[j]+1, t[i]=j;}
		else
		  if(dp[i]==dp[j]+1)
		    {
		      if(a[j]<a[t[i]]){ dp[i]=dp[j]+1, t[i]=j;}
		    }
		
	      }
      
	  }
	if(dp[i]==oo)dp[i]=1;
	}
      goto eticheta;
    }
  
  for(i=n-1;i>=1;--i)
    {
      min=oo;
      Dp=oo;
         dp[i]=oo;
      for(j=i+1;j<=n;++j)
	if(a[i]<=a[j])
	  {
	    /*
	    
	    if(dp[i]>dp[j]+1)
	      {
		if(a[j]<min || a[i]>min)dp[i]=dp[j]+1, t[i]=j, p=j;
	      }
	    else 
	      if(dp[i]==dp[j]+1)
		{
		  if(a[j]<min && (a[j]<a[p] || a[i]>min)) dp[i]=dp[j]+1, t[i]=j, p=j;
		}
	    */
	    if(min>a[j]) min=a[j], p=j, Dp=dp[j];
	       else if(min==a[j] && dp[j]<=Dp){ min=a[j], p=j, Dp=dp[j];}
	  }
       if(min!=oo)
      	{
          dp[i]=dp[p]+1;
        t[i]=p;
      }
      else dp[i]=1;
    }
  //for(i=1;i<=n;++i)printf("%d ", dp[i]);
 eticheta:
  int poz=1, max=dp[1];
  for(i=2;i<=n;++i) if(max<dp[i] && dp[i]!=oo && first[i])max=dp[i], poz=i;
  else if(max==dp[i] && first[i]) if(a[i]<a[poz]) max=dp[i], poz=i;

  for(i=poz;i!=0;i=t[i]) Q[++nq]=i;

  freopen("subsir2.out","w",stdout);
  printf("%d\n", nq);
  for(i=1;i<=nq;++i)printf("%d ", Q[i]);
  printf("\n");
  return 0;
}