zafu 1467

终于把校赛最后一题过了,二分的地方写的很差,以后注意改进。思路就是从前向后求LIS最长递增子序列,以a[i]为底LIS值记录在dp1[i],

然后从后向前求LDS最长递减子序列,以a[i]为底LDS值记录在dp2[i]

则如果 dp1[i] + dp2[i]== dp[n]+1( 即最长长度加1 ),则说明a[i]是最长中的某个数,如果这些符合的dp1[i]值只出现一次,则其为

Key Number

题目链接 http://info.zjfc.edu.cn/acm/problemDetail.aspx?pid=1467

代码
   
     
#include < stdio.h >

#define maxn 100005
int dp1[maxn],dp2[maxn];
int a[maxn];
int hash[maxn];
int stack[maxn];
int n;
int kin;

void LIS( int k )
{
int i,j;
int end,front,mid;

int top = 1 ;
stack[top]
= a[k];
dp1[
1 ] = 1 ;

for ( i = k + 1 ; i <= n ; i ++ )
{
if ( a[i] > stack[ top ] )
{
stack[
++ top ] = a[i] ;
dp1[i]
= top; //
}
else if ( a[i] <= stack[ 1 ] )
{
stack[
1 ] = a[i];
dp1[i]
= 1 ;
}
else
{
front
= 1 ;
end
= top;
while ( end >= front )
{
mid
= ( front + end ) / 2 ;
if ( a[i] == stack[mid] )
{
dp1[i]
= mid;
break ;
}
else if ( a[i] > stack[mid] && a[i] <= stack[mid + 1 ] )
{
stack[mid
+ 1 ] = a[i] ;
dp1[i]
= mid + 1 ; //
break ;
}
else if ( a[i] < stack[mid] )
end
= mid - 1 ;
else if (a[i] > stack[mid + 1 ] )
front
= mid + 1 ;

}

}

}
kin
= top;
}


void LDS( int k )
{
int i,j;
int end,front,mid;
int top = 1 ;
stack[top]
= a[k];
dp2[k]
= 1 ;
for ( i = k - 1 ; i > 0 ; i -- )
{
if ( a[i] < stack[ top ] )
{
stack[
++ top ] = a[i] ;
dp2[i]
= top;
}
else if ( a[i] >= stack[ 1 ] )
{
stack[
1 ] = a[i];
dp2[i]
= 1 ;
}
else
{
front
= 1 ;
end
= top;
while ( end >= front )
{
mid
= ( front + end ) / 2 ;
if ( a[i] == stack[mid] )
{
dp2[i]
= mid;
break ;
}
else if ( a[i] < stack[mid] && a[i] >= stack[mid + 1 ] )
{
stack[mid
+ 1 ] = a[i] ;
dp2[i]
= mid + 1 ;
break ;
}
else if ( a[i] > stack[mid] )
end
= mid - 1 ;
else if (a[i] < stack[mid + 1 ] )
front
= mid + 1 ;

}

}

}

}

int main()
{
int t,i,j,k;
scanf(
" %d " , & t);
while ( t -- && scanf( " %d " , & n) != EOF )
{
for ( i = 0 ; i <= n; i ++ ) // 初始
hash[ i ] = 0 ;

for (i = 1 ;i <= n;i ++ )
scanf(
" %d " , & a[i] );

LIS(
1 ) ;
LDS( n ) ;

for ( i = 1 ;i <= n;i ++ )
{
if ( dp1[i] + dp2[i] == kin + 1 )
hash[ dp1[i] ]
++ ;
}

int sum = 0 ;
for (i = 1 ;i <= n;i ++ )
if ( hash[i] == 1 )
sum
++ ;

printf(
" %d\n " ,sum);
}

return 0 ;
}

 

 


 

 

你可能感兴趣的:(a)