hdu3998 Sequence(最大流,LIS)

转载请注明出处: 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).
 


Input
The input file have many cases. Each case will give a integer number n.The next line will 
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长度的不相交的上升序列的个数

分析:

n求出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\n",ans);

147         printf("%d\n",Dinic(s,t));

148             

149     }

150     return 0;

151 }
代码君

 

你可能感兴趣的:(sequence)