【网络流24题】 最长递增子序列问题
(题目复制自洛谷)
题目描述
给定正整数序列x1,...,xn 。
(1)计算其最长递增子序列的长度s。
(2)计算从给定的序列中最多可取出多少个长度为s的递增子序列。
(3)如果允许在取出的序列中多次使用x1和xn,则从给定序列中最多可取出多少个长度为s的递增子序列。
编程任务:
设计有效算法完成(1)(2)(3)提出的计算任务。
输入输出格式
输入格式:
第1 行有1个正整数n,表示给定序列的长度。接下来的1 行有n个正整数n:x1, ..., xn。
输出格式:
第1 行是最长递增子序列的长度s。第2行是可取出的长度为s 的递增子序列个数。第3行是允许在取出的序列中多次使用x1和xn时可取出的长度为s 的递增子序列个数。
输入输出样例
输入样例#1:
4
3 6 2 5
输出样例#1:
2
2
3
以前做过,再复习一下网络流。
1 program alis(input,output); 2 const 3 inf=123456789; 4 type 5 etype=record 6 t,c,next,rev:longint; 7 end; 8 var 9 a,d,cur:array[-550..550]of longint; 10 e:array[0..1000010]of etype; 11 f,x:array[0..500]of longint; 12 q:array[0..1010]of longint; 13 n,i,j,ans,h,t,cnt,r:longint; 14 function max(a,b:longint):longint; 15 begin 16 if a>b then exit(a) else exit(b); 17 end; 18 function min(a,b:longint):longint; 19 begin 20 if a<b then exit(a) else exit(b); 21 end; 22 procedure ins(x,y,c:longint); 23 begin 24 inc(cnt);e[cnt].t:=y;e[cnt].c:=c;e[cnt].next:=a[x];a[x]:=cnt; 25 end; 26 procedure add(x,y,c:longint); 27 begin 28 ins(x,y,c);e[cnt].rev:=cnt+1;ins(y,x,0);e[cnt].rev:=cnt-1; 29 end; 30 procedure bfs; 31 begin 32 for i:=-n to n+1 do d[i]:=-1; 33 h:=0;t:=1;q[1]:=0;d[0]:=0; 34 while h<t do 35 begin 36 inc(h);i:=a[q[h]]; 37 while i<>0 do 38 begin 39 if (e[i].c>0) and (d[e[i].t]=-1) then 40 begin 41 d[e[i].t]:=d[q[h]]+1; 42 inc(t);q[t]:=e[i].t; 43 end; 44 i:=e[i].next; 45 end; 46 end; 47 end; 48 function dfs(k,f:longint):longint; 49 var 50 ans,r,i:longint; 51 begin 52 if (k=n+1) or (f=0) then exit(f); 53 ans:=0;i:=cur[k]; 54 while i<>0 do 55 begin 56 if (d[e[i].t]=d[k]+1) and (e[i].c>0) then 57 begin 58 r:=dfs(e[i].t,min(f,e[i].c)); 59 dec(e[i].c,r);inc(e[e[i].rev].c,r); 60 inc(ans,r);dec(f,r); 61 if f=0 then break; 62 end; 63 i:=e[i].next; 64 cur[k]:=i; 65 end; 66 if f>0 then d[k]:=-1; 67 exit(ans); 68 end; 69 function maxflow:longint; 70 var 71 ans:longint; 72 begin 73 ans:=0; 74 while true do 75 begin 76 bfs; 77 if d[n+1]=-1 then break; 78 for i:=-n to n+1 do cur[i]:=a[i]; 79 ans:=ans+dfs(0,inf); 80 end; 81 exit(ans); 82 end; 83 begin 84 assign(input,'alis.in');assign(output,'alis.out');reset(input);rewrite(output); 85 readln(n); 86 for i:=1 to n do read(x[i]); 87 ans:=0; 88 for i:=1 to n do 89 begin 90 f[i]:=1; 91 for j:=1 to i-1 do 92 if x[j]<=x[i] then f[i]:=max(f[i],f[j]+1); 93 ans:=max(ans,f[i]); 94 end; 95 writeln(ans); 96 fillchar(a,sizeof(a),0);cnt:=0; 97 for i:=1 to n do add(-i,i,1); 98 for i:=1 to n do if f[i]=1 then add(0,-i,1); 99 for i:=2 to n do for j:=1 to i-1 do if (f[i]=f[j]+1) and (x[j]<=x[i]) then add(j,-i,1); 100 for i:=1 to n do if f[i]=ans then add(i,n+1,1); 101 r:=maxflow;writeln(r); 102 add(0,1,inf);if f[n]=ans then add(-n,n+1,inf); 103 writeln(r+maxflow); 104 close(input);close(output); 105 end.