转载请注明出处: http://www.cnblogs.com/fraud/ ——by fraud
Sequence
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1589 Accepted Submission(s): 587
Problem Description
There is a sequence X (i.e. x[1], x[2], ..., x[n]). We define increasing subsequence of X
as x[i1], x[i2],...,x[ik], which satisfies follow conditions:
1) x[i1] < x[i2],...,<x[ik];
2) 1<=i1 < i2,...,<ik<=n
As an excellent program designer, you must know how to find the maximum length of the
increasing sequense, which is defined as s. Now, the next question is how many increasing
subsequence with s-length can you find out from the sequence X.
For example, in one case, if s = 3, and you can find out 2 such subsequence A and B from X.
1) A = a1, a2, a3. B = b1, b2, b3.
2) Each ai or bj(i,j = 1,2,3) can only be chose once at most.
Now, the question is:
1) Find the maximum length of increasing subsequence of X(i.e. s).
2) Find the number of increasing subsequence with s-length under conditions described (i.e. num).
as x[i1], x[i2],...,x[ik], which satisfies follow conditions:
1) x[i1] < x[i2],...,<x[ik];
2) 1<=i1 < i2,...,<ik<=n
As an excellent program designer, you must know how to find the maximum length of the
increasing sequense, which is defined as s. Now, the next question is how many increasing
subsequence with s-length can you find out from the sequence X.
For example, in one case, if s = 3, and you can find out 2 such subsequence A and B from X.
1) A = a1, a2, a3. B = b1, b2, b3.
2) Each ai or bj(i,j = 1,2,3) can only be chose once at most.
Now, the question is:
1) Find the maximum length of increasing subsequence of X(i.e. s).
2) Find the number of increasing subsequence with s-length under conditions described (i.e. num).
Input
The input file have many cases. Each case will give a integer number n.The next line will
have n numbers.
have n numbers.
Output
The output have two line. The first line is s and second line is num.
Sample Input
4
3 6 2 5
Sample Output
2
2
Source
题意:
给出一个序列,问LIS的长度以及长度为LIS长度的不相交的上升序列的个数
分析:
n2 求出LIS,同时维护好信息,然后构图。
若dp[i]=1,则由源点向该点连一条容量为1的边,若dp[i]=dp[j]+1,则由j向i连一条容量为1的边,若dp[i]=LIS的长度,则由i向汇点连一条容量为1的边。
注意要拆点。虽然这题数据比较水,不拆点也能过。
1 //##################### 2 //Author:fraud 3 //Blog: http://www.cnblogs.com/fraud/ 4 //##################### 5 #include <iostream> 6 #include <sstream> 7 #include <ios> 8 #include <iomanip> 9 #include <functional> 10 #include <algorithm> 11 #include <vector> 12 #include <string> 13 #include <list> 14 #include <queue> 15 #include <deque> 16 #include <stack> 17 #include <set> 18 #include <map> 19 #include <cstdio> 20 #include <cstdlib> 21 #include <cmath> 22 #include <cstring> 23 #include <climits> 24 #include <cctype> 25 using namespace std; 26 #define XINF INT_MAX 27 #define INF 0x3FFFFFFF 28 #define MP(X,Y) make_pair(X,Y) 29 #define PB(X) push_back(X) 30 #define REP(X,N) for(int X=0;X<N;X++) 31 #define REP2(X,L,R) for(int X=L;X<=R;X++) 32 #define DEP(X,R,L) for(int X=R;X>=L;X--) 33 #define CLR(A,X) memset(A,X,sizeof(A)) 34 #define IT iterator 35 typedef long long ll; 36 typedef pair<int,int> PII; 37 typedef vector<PII> VII; 38 typedef vector<int> VI; 39 struct edge{ 40 int to,cap,rev; 41 edge(int _to,int _cap,int _rev) 42 { 43 to=_to; 44 cap=_cap; 45 rev=_rev; 46 } 47 }; 48 const int MAX_V=10020; 49 vector<edge>G[MAX_V]; 50 int iter[MAX_V]; 51 int level[MAX_V]; 52 int tot=0; 53 void add_edge(int from,int to,int cap) 54 { 55 G[from].PB(edge(to,cap,G[to].size())); 56 G[to].PB(edge(from,0,G[from].size()-1)); 57 } 58 void bfs(int s,int t) 59 { 60 CLR(level,-1); 61 queue<int>q; 62 level[s]=0; 63 q.push(s); 64 while(!q.empty()) 65 { 66 int u=q.front(); 67 q.pop(); 68 for(int i=0;i<G[u].size();i++) 69 { 70 edge &e=G[u][i]; 71 if(e.cap>0&&level[e.to]<0) 72 { 73 level[e.to]=level[u]+1; 74 q.push(e.to); 75 } 76 } 77 } 78 } 79 int dfs(int v,int t,int f) 80 { 81 if(v==t)return f; 82 for(int &i=iter[v];i<G[v].size();i++) 83 { 84 edge &e=G[v][i]; 85 if(e.cap>0&&level[v]<level[e.to]) 86 { 87 int d=dfs(e.to,t,min(f,e.cap)); 88 if(d>0) 89 { 90 e.cap-=d;; 91 G[e.to][e.rev].cap+=d; 92 return d; 93 } 94 } 95 } 96 return 0; 97 } 98 int Dinic(int s,int t) 99 { 100 int flow=0; 101 for(;;) 102 { 103 bfs(s,t); 104 if(level[t]<0)return flow; 105 memset(iter,0,sizeof(iter)); 106 int f; 107 while((f=dfs(s,t,INF))>0) 108 { 109 flow+=f; 110 } 111 } 112 } 113 114 int a[MAX_V]; 115 int dp[MAX_V]; 116 int main() 117 { 118 ios::sync_with_stdio(false); 119 int n; 120 while(scanf("%d",&n)!=EOF){ 121 for(int i=0;i<n;i++) 122 scanf("%d",&a[i]); 123 int ans=0; 124 CLR(dp,0); 125 for(int i=0;i<n;i++){ 126 dp[i]=1; 127 for(int j=0;j<i;j++){ 128 if(a[j]<a[i]){ 129 dp[i]=max(dp[i],dp[j]+1); 130 } 131 } 132 ans=max(ans,dp[i]); 133 } 134 int s=2*n,t=2*n+1; 135 for(int i=0;i<t+1;i++)G[i].clear(); 136 for(int i=0;i<n;i++)add_edge(i,i+n,1); 137 for(int i=0;i<n;i++){ 138 if(dp[i]==1)add_edge(s,i,1); 139 if(dp[i]==ans)add_edge(i+n,t,1); 140 for(int j=i+1;j<n;j++){ 141 if(dp[j]==dp[i]+1&&a[i]<a[j]){ 142 add_edge(i+n,j,1); 143 } 144 } 145 } 146 printf("%d ",ans); 147 printf("%d ",Dinic(s,t)); 148 149 } 150 return 0; 151 }