POJ 1836 Alignment

解题思路:正反方向最长递增子序列(参照POJ2533),然后枚举中心

 

  
    
#include < iostream >
using namespace std;
int n;
float num[ 1000 ],B[ 1001 ];
inline
void LIS( int * h, bool isLeft)
{
int i,j,p,q,m,len;
if ( ! isLeft) for (i = 0 ,j = n / 2 ;i < j;i ++ )swap(num[i],num[n - 1 - i]);
for (B[ 0 ] = 0 ,B[ 1 ] = num[ 0 ],h[ 0 ] = len = 1 ,i = 1 ;i < n;i ++ ) // 最长递增子序列
{
for (p = 0 ,q = len,m = (p + q) / 2 ;p <= q;m = (p + q) / 2 )
if (B[m] < num[i])p = m + 1 ; else q = m - 1 ;
B[p]
= num[i]; if (p > len)len ++ ;h[i] = p;
}
if ( ! isLeft) for (i = 0 ,j = n / 2 ;i < j;i ++ )swap(h[i],h[n - 1 - i]);
}
int main()
{
int i,j,k,l[ 1000 ],r[ 1000 ],ans,m1,m1i,m;
scanf(
" %d " , & n);
for (i = 0 ;i < n;i ++ )scanf( " %f " , & num[i]);
LIS(l,
1 );LIS(r, 0 );
for (i = 1 ;i < n;i ++ ) if (l[i] < l[i - 1 ])l[i] = l[i - 1 ];
for (i = n - 2 ;i >= 0 ;i -- ) if (r[i] < r[i + 1 ])r[i] = r[i + 1 ];
for (ans = i = 0 ;i < n - 1 ;i ++ ) if (ans < l[i] + r[i + 1 ])ans = l[i] + r[i + 1 ];//枚举中心点
printf(
" %d\n " , n - ans);
return 0 ;
}

 

 

你可能感兴趣的:(poj)