思路:题目要求是先找到一个非递减序列(即i<j时ai<=aj),然后再找一个非递增序列(即i>j时ai<=aj),由此我们可以想到我们先找一个单调递增序列然后再找一个单调递减序列,我们可以在找第二个序列的时候可以从原序列倒着找,这样就相当于找两个单调递增子序列。然后再对应相加减一即为结果(减一是因为最终结果序列的最大值用了两遍)。
样例: 1 4 2 5 1
第一个序列:1 2 2 3 3
第二个序列:2 3 2 2 1
结果序列: 3 5 4 5 4
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define ll long long #define INF 0x3f3f3f using namespace std; ll a[500010],b[500010],c1[500010],c2[500010]; ll dp1[500010],dp2[500010]; ll n; void LCIS(ll c[],ll num[],ll dp[]) { ll len=0; for(int i=1;i<=n;i++) { ll j=upper_bound(c+1,c+1+len,num[i])-c; c[j]=num[i]; dp[i]=j; len=max(len,j); } } int main() { while(scanf("%lld",&n)!=EOF) { for(int i=1,j=n;i<=n;j--,i++) { scanf("%lld",&a[i]); b[j]=a[i]; c1[i]=c2[i]=INF; } memset(dp1,0,sizeof(dp1)); memset(dp2,0,sizeof(dp2)); // printf("##\n"); LCIS(c1,a,dp1); LCIS(c2,b,dp2); ll ans=0; for(int i=1;i<=n;i++) { ans=max(ans,dp1[i]+dp2[n-i+1]-1); } printf("%lld\n",ans); } return 0; }