对于第一问直接n^2dp计算
第二问建图跑网络流
第三问将起始与结尾流量开大
建边的时候要严格按照子序列求法建
By:大奕哥
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=10005; 4 int head[N],d[N],f[N],a[N]; 5 int n,m,cnt=-1,s,t,sum; 6 struct node{ 7 int to,nex,w; 8 }e[1000005]; 9 void add(int x,int y,int w) 10 { 11 e[++cnt].to=y;e[cnt].nex=head[x];head[x]=cnt;e[cnt].w=w; 12 e[++cnt].to=x;e[cnt].nex=head[y];head[y]=cnt;e[cnt].w=0; 13 } 14 queue<int>q; 15 bool bfs(int x,int y) 16 { 17 memset(d,-1,sizeof(d)); 18 d[x]=0;q.push(x); 19 while(!q.empty()) 20 { 21 int x=q.front();q.pop(); 22 for(int i=head[x];i!=-1;i=e[i].nex) 23 { 24 int y=e[i].to; 25 if(d[y]!=-1||!e[i].w)continue; 26 d[y]=d[x]+1;q.push(y); 27 } 28 } 29 return d[y]!=-1; 30 } 31 int dfs(int x,int w,int yy) 32 { 33 if(x==yy||!w)return w; 34 int s=0; 35 for(int i=head[x];i!=-1;i=e[i].nex) 36 { 37 int y=e[i].to; 38 if(!e[i].w||d[y]!=d[x]+1)continue; 39 int flow=dfs(y,min(w-s,e[i].w),yy); 40 if(!flow){ 41 d[y]=-1;continue; 42 } 43 e[i].w-=flow;e[i^1].w+=flow;s+=flow; 44 if(s==w)return s; 45 } 46 return s; 47 } 48 int dinic() 49 { 50 int ans=0; 51 while(bfs(s,t)) 52 { 53 ans+=dfs(s,1e9,t); 54 } 55 return ans; 56 } 57 int main() 58 { 59 60 freopen("1.out","r",stdin); 61 freopen("my.out","w",stdout); 62 scanf("%d",&n); 63 memset(head,-1,sizeof(head)); 64 for(int i=1;i<=n;++i) 65 { 66 scanf("%d",&a[i]); 67 add(i,i+n,1); 68 } 69 s=0,t=n+n+10;int ans=1; 70 for(int i=1;i<=n;++i) 71 { 72 f[i]=max(f[i],1);add(i,i+n,1); 73 for(int j=i+1;j<=n;++j) 74 if(a[j]>=a[i]) 75 { 76 f[j]=max(f[j],f[i]+1); 77 ans=max(f[j],ans); 78 } 79 }int pre=ans; 80 for(int i=1;i<=n;++i) 81 for(int j=i+1;j<=n;++j) 82 if(f[j]==f[i]+1&&a[j]>=a[i]) 83 add(i+n,j,1); 84 printf("%d ",ans); 85 for(int i=1;i<=n;++i) 86 {if(f[i]==1)add(s,i,1); 87 if(f[i]==ans)add(i+n,t,1);} 88 ans=dinic(); 89 printf("%d ",ans); 90 add(s,1,1e9);add(1,n+1,1e9); 91 if(f[n]==pre) 92 add(n+n,t,1e9),add(n,n+n,1e9); 93 ans+=dinic(); 94 printf("%d ",ans); 95 return 0; 96 }