HDU 4604 deque 最长上升子序列

枚举每个位置,求以num[i]为起点的最长不下降子序列和以num[i]为结尾的最长不递增子序列。

并且把相同值的个数统计一下,最后要减去算重复了的。

比如:

1

9

4 4 2 2 2 3 3 3 7

#include <cstdio>
#include <cstring>
#include <algorithm> using namespace std; const int MAXN = + ; int n;
int num[MAXN];
int stack1[MAXN];
int stack2[MAXN];
int dp1[MAXN];
int dp2[MAXN];
int same1[MAXN];
int same2[MAXN]; void DP( int *stack, int *dp, int *same )
{
int top = ; stack[ ++top ] = num[]; dp[] = ;
same[] = ;
int temp; for ( int i = ; i < n; i++ )
{
int x = upper_bound( stack + , stack + top + , num[i] ) - stack;
int y = lower_bound( stack + , stack + top + , num[i] ) - stack; if ( num[i] >= stack[top] )
{
stack[ ++top ] = num[i];
temp = top;
}
else
{
stack[x] = num[i];
temp = x;
}
dp[i] = temp;
same[i] = x - y + ;
} return;
} int main()
{
int T;
scanf("%d", &T);
while ( T-- )
{
scanf( "%d", &n );
for ( int i = n - ; i >= ; --i )
scanf( "%d", &num[i] ); DP( stack1, dp1, same1 ); for ( int i = ; i < n; ++i )
{
// printf( "%d ", num[i] );
num[i] = -num[i];
}
//puts("");
DP( stack2, dp2, same2 ); int ans = ;
for ( int i = ; i < n; ++i )
{
//printf( "%d %d\n", dp1[i], dp2[i] );
//printf( "**%d %d\n", same1[i], same2[i] );
ans = max( ans, dp1[i] + dp2[i] - min( same1[i], same2[i] ) );
} printf( "%d\n", ans );
}
return ;
}
上一篇:node-webkit学习之【无边框窗口用JS实现拖动改变大小等】


下一篇:js窗口拖动 模版