记录编号 221127 评测结果 AAAAAAAAAA
题目名称 [网络流24题] 最长递增子序列 最终得分 100
用户昵称 Gravatar23333 是否通过 通过
代码语言 C++ 运行时间 0.006 s
提交时间 2016-01-21 20:17:45 内存使用 14.08 MiB
显示代码纯文本
#include<bits/stdc++.h>
#define inf 214748347
#define N 1023
#define rep(i,l,r) for(int i=l;i<=r;i++)
int head[N],dis[N],tot=1,n,T,sum,ans,a[N],cur[N],f[N],k;
using namespace std;
struct Edge{
   int to,next,w;
}e[1201000];
inline void ins(int u,int v,int w) {
   e[++tot].to=v; e[tot].next=head[u]; head[u]=tot; e[tot].w=w;
}
inline int read() {
	 int x=0; char ch=getchar();
	 while(ch<'0' || ch>'9') ch=getchar();
	 while(ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar();
	 return x;
}
inline bool bfs(){
   rep(i,0,T) dis[i]=-1; queue<int>q; q.push(0); dis[0]=0;
   while(!q.empty()) {
   	 int x=q.front(); q.pop();
  	 for(int k=head[x];k;k=e[k].next) 
 	    if(dis[e[k].to]<0 && e[k].w>0) {
 	    	  dis[e[k].to]=dis[x]+1; q.push(e[k].to);
 	    }
   }
   if(dis[T]>0) return 1;else return 0;
}
int find(int x,int low){
   if(x==T) return low;
   int delta=low,now;
   for(int k=cur[x];k;k=e[k].next) 
     if(e[k].w>0 && dis[e[k].to]==dis[x]+1){ 
         now=find(e[k].to,min(e[k].w,delta));
         e[k].w-=now; e[k^1].w+=now;   delta-=now;
         if(!delta){
         	 cur[x]=k;return low;
         }	
      } 
   dis[x]=-1;
   return low-delta;
}
void Dinic() {
	 while(bfs()) {
	 	 memcpy(cur,head,(T+1)<<2); while(sum=find(0,inf)) ans+=sum;
	 }
}
int main () {
   freopen("alis.in","r",stdin); freopen("alis.out","w",stdout);
   n=read(); rep(i,1,n)a[i]=read();  T=n+n+1;
   rep(i,1,n) {
   	 f[i]=1; rep(j,1,i-1) if(a[j]<=a[i]) f[i]=max(f[i],f[j]+1);
		k=max(k,f[i]);
   }
   printf("%d\n",k);
   
   rep(i,1,n) ins(i,i+n,1),ins(i+n,i,0);
   rep(i,1,n) if(f[i]==1)ins(0,i,1),ins(i,0,0);else if(f[i]==k) ins(i+n,T,1),ins(T,i+n,0);
   rep(i,1,n) 
     rep(j,i+1,n) if(a[j]>=a[i] && 1+f[i]==f[j])  ins(i+n,j,1),ins(j,i+n,0);
   Dinic();
   if(!ans)printf("%d\n",n);else printf("%d\n",ans); ans=0;
   
   memset(head,0,(T+1)<<2);   tot=1;
   rep(i,2,n-1) ins(i,i+n,1),ins(i+n,i,0);
   rep(i,2,n-1)	if(f[i]==1) ins(0,i,1),ins(i,0,0);else if(f[i]==k) ins(i+n,T,1),ins(T,i+n,0);
   ins(1,1+n,inf),ins(1+n,1,0); if(f[1]==1) ins(0,1,inf),ins(1,0,0);else if(f[1]==k) ins(1+n,T,inf),ins(T,1+n,0);
   ins(n,n+n,inf),ins(n+n,n,0); if(f[n]==1) ins(0,n,inf),ins(n,0,0);else if(f[n]==k) ins(n+n,T,inf),ins(T,n+n,0);
   rep(i,1,n)
     rep(j,i+1,n) if(a[j]>=a[i] && f[i]+1==f[j])  ins(i+n,j,1),ins(j,i+n,0);
   Dinic();
   if(!ans)printf("%d\n",n);else printf("%d\n",ans); ans=0;
   fclose(stdin); fclose(stdout);
   return 0;
}