Paul·Shi @ 2018-10-01 19:00:05
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define MAXN 5010
#define MAXM 400010
using namespace std;
inline int read ()
{
int s=0,w=1;
char ch=getchar ();
while (ch<'0'||ch>'9'){if (ch=='-') w=-1;ch=getchar ();}
while ('0'<=ch&&ch<='9') s=(s<<1)+(s<<3)+(ch^48),ch=getchar ();
return s*w;
}
struct edge{
int v,w,nxt;
}e[MAXM<<1];
int n,s,t,ans,cnt;
int a[MAXN],f[MAXN];
int head[MAXN],cur[MAXN],dis[MAXN];
void Problem1 ()
{
for (int i=1;i<=n;i++)
f[i]=1;
for (int i=n;i>=1;i--)
for (int j=n;j>i;j--)
if (a[i]<=a[j])
f[i]=max (f[i],f[j]+1);
for (int i=1;i<=n;i++) ans=max (ans,f[i]);
printf ("%d\n",ans);
}
void add (int u,int v,int w)
{
e[cnt].v=v;e[cnt].w=w;
e[cnt].nxt=head[u];head[u]=cnt++;
}
void auto_add (int u,int v,int w)
{
add (u,v,w);add (v,u,w);
}
bool bfs ()
{
memset (dis,0,sizeof (dis));
queue<int>q;
q.push (s);dis[s]=1;
while (!q.empty ())
{
int u=q.front ();q.pop ();
for (int i=head[u];i!=-1;i=e[i].nxt)
if (e[i].w&&!dis[e[i].v])
dis[e[i].v]=dis[u]+1,q.push (e[i].v);
}
return dis[t]!=0;
}
int dfs (int u,int flow)
{
if (u==t) return flow;
for (int &i=cur[u];i!=-1;i=e[i].nxt)
if (dis[e[i].v]==dis[u]+1&&e[i].w)
{
int fl=dfs (e[i].v,min (flow,e[i].w));
if (fl)
{
e[i].w-=fl;
e[i^1].w+=fl;
return fl;
}
}
return 0;
}
int Dinic ()
{
int Max_flow=0;
while (bfs ())
{
for (int i=s;i<=t;i++)
cur[i]=head[i];
while (int d=dfs (s,INF))
Max_flow+=d;
}
return Max_flow;
}
void Problem2 ()
{
memset (head,-1,sizeof (head));
s=0,t=(n<<1|1);
for (int i=1;i<=n;i++)
if (f[i]==ans)
auto_add (s,i,1);
for (int i=1;i<=n;i++)
auto_add (i,i+n,1);
for (int i=1;i<=n;i++)
if (f[i]==1) auto_add (i+n,t,1);
for (int i=1;i<=n;i++)
for (int j=1;j<i;j++)
if (a[j]<=a[i]&&f[j]==f[i]+1)
auto_add (j+n,i,1);
printf ("%d\n",Dinic());
}
void Problem3 ()
{
memset (head,-1,sizeof (head));cnt=0;
for (int i=2;i<=n;i++)
if (f[i]==ans)
auto_add (s,i,1);
for (int i=2;i<n;i++)
auto_add (i,i+n,1);
if (f[1]==ans) auto_add (s,1,INF);
auto_add (1,1+n,INF);
auto_add (n,n<<1,INF);
if (f[n]==1) auto_add (n<<1,t,INF);
for (int i=1;i<n;i++)
if (f[i]==1) auto_add (i+n,t,1);
for (int i=1;i<=n;i++)
for (int j=1;j<i;j++)
if (a[j]<=a[i]&&f[j]==f[i]+1)
auto_add (j+n,i,1);
printf ("%d\n",Dinic());
}
int main()
{
n=read ();
for (int i=1;i<=n;i++) a[i]=read ();
Problem1 ();
Problem2 ();
Problem3 ();
return 0;
}