第一问暴力$O(n^2)$转移就行了
第二问有坑,题目的意思是从序列里取出来一些数,取出来的数不放回去,才有了第三问
图还是比较好建的吧,源点向$f[i]=1$的点连流量为$1$的边,点$i$向$f[j]=f[i]+1$的$j$点连流量为$1$的边,$f[i]=s$的$i$点向汇点连流量为$1$的边
这样建图,保证了每一条流向汇点的流量都是跑了$s$条边的。
然后跑最大流就行了
第三问细节比较多,题目也有坑
首先题目的意思是$x1,xn$可以出现在多组最长不下降子序列中,但在一组里只能出现一次!
源点向$1$连流量为$inf$的边,$n$向汇点连流量为$inf$的边
然而可能会出现$f[n]!=s$的情况,会导致$1$的流量经过少于$s$条边到达$n$点
还会出现$s=1$的情况,不能特判掉等等
提供一组数据吧
23
749 917 271 938 366 953 64 723 678 448 754 112 831 228 684 601 506 121 6 417 382 724 1
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #define N1 505 5 #define M1 50010 6 #define ll long long 7 #define dd double 8 #define inf 0x3f3f3f3f 9 using namespace std; 10 11 int gint() 12 { 13 int ret=0,fh=1;char c=getchar(); 14 while(c<‘0‘||c>‘9‘){if(c==‘-‘)fh=-1;c=getchar();} 15 while(c>=‘0‘&&c<=‘9‘){ret=ret*10+c-‘0‘;c=getchar();} 16 return ret*fh; 17 } 18 int n,m,nn,S,T,len; 19 int a[N1]; 20 struct Edge{ 21 int head[N1],to[M1<<1],nxt[M1<<1],flow[M1<<1],cte; 22 void ae(int u,int v,int F) 23 { 24 cte++; to[cte]=v; flow[cte]=F; 25 nxt[cte]=head[u]; head[u]=cte; 26 } 27 }e,E; 28 29 int que[N1],hd,tl,dep[N1],cur[N1]; 30 int bfs() 31 { 32 int x,j,v; 33 memset(dep,-1,sizeof(dep)); memcpy(cur,E.head,sizeof(cur)); 34 hd=1,tl=0; que[++tl]=S; dep[S]=0; 35 while(hd<=tl) 36 { 37 x=que[hd++]; 38 for(j=E.head[x];j;j=E.nxt[j]) 39 { 40 v=E.to[j]; 41 if( dep[v]==-1 && E.flow[j]>0 ) 42 dep[v]=dep[x]+1, que[++tl]=v; 43 } 44 } 45 return dep[T]!=-1; 46 } 47 int dfs(int x,int limit) 48 { 49 int j,v,flow,ans=0; if(x==T||!limit) return limit; 50 for(j=cur[x];j;j=E.nxt[j]) 51 { 52 cur[x]=j; v=E.to[j]; 53 if( dep[v]==dep[x]+1 && (flow=dfs(v,min(E.flow[j],limit))) ) 54 { 55 limit-=flow; ans+=flow; 56 E.flow[j]-=flow; E.flow[j^1]+=flow; 57 if(!limit) break; 58 } 59 } 60 return ans; 61 } 62 int f[N1],vis[N1]; 63 int Dinic1() 64 { 65 int mxflow=0; 66 memcpy(&E,&e,sizeof(E)); 67 while(bfs()) mxflow+=dfs(S,inf); 68 return mxflow; 69 } 70 int Dinic2() 71 { 72 int mxflow=0,i; 73 memcpy(&E,&e,sizeof(E)); 74 E.ae(S,1,inf),E.ae(1,S,0); 75 E.ae(n,T,inf),E.ae(T,n,0); 76 while(bfs()) mxflow+=dfs(S,inf); 77 if(len!=1&&(f[n]!=len||f[1]+1>f[n])) mxflow--; 78 return mxflow; 79 } 80 81 int main() 82 { 83 scanf("%d",&n); 84 int i,j; S=n+1,T=n+2; e.cte=1; 85 for(i=1;i<=n;i++) a[i]=gint(); 86 for(i=1;i<=n;i++) 87 for(j=1,f[i]=1;j<i;j++) if(a[j]<=a[i]) 88 f[i]=max(f[i],f[j]+1); 89 for(i=1;i<=n;i++) len=max(len,f[i]); 90 printf("%d\n",len); 91 for(i=1;i<=n;i++) 92 { 93 if(f[i]==len) e.ae(i,T,1), e.ae(T,i,0); 94 if(f[i]==1) e.ae(S,i,1), e.ae(i,S,0); 95 else{ 96 for(j=1;j<i;j++) 97 if(f[i]==f[j]+1&&a[j]<=a[i]) 98 e.ae(j,i,1), e.ae(i,j,0); 99 } 100 } 101 printf("%d\n",Dinic1()); 102 printf("%d\n",Dinic2()); 103 return 0; 104 }
原文:https://www.cnblogs.com/guapisolo/p/10293261.html