• 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
    ",ans);
    147         printf("%d
    ",Dinic(s,t));
    148             
    149     }
    150     return 0;
    151 }
    代码君
  • 相关阅读:
    linux下详解shell中>/dev/null 2>&1
    关于使用sublime的一些报错异常退出的解决方法
    Linux下如何挂载文件,并设置开机自动挂载
    关于/var/log/maillog 时间和系统时间不对应的问题 -- 我出现的是日志时间比系统时间慢12个小时
    如何在含有json类型的字段上建立多列索引
    文件大小
    SVN
    索引
    MD5验证
    协议适配器错误的问题
  • 原文地址:https://www.cnblogs.com/fraud/p/4354725.html
Copyright © 2020-2023  润新知