zoukankan      html  css  js  c++  java
  • 【网络流24题】最长递增子序列

    Description

    给定正整数序列x1,..., xn。
    (1)计算其最长递增子序列的长度s。
    (2)计算从给定的序列中最多可取出多少个长度为s的递增子序列。
    (3)如果允许在取出的序列中多次使用x1和xn,则从给定序列中最多可取出多少个长度为s的递增子序列。
    设计有效算法完成(1)(2)(3)提出的计算任务

    Input

    第1 行有1个正整数n(n<=500),表示给定序列的长度。
    接下来的1 行有n个正整数x1,..., xn。

    Output

    第1 行是最长递增子序列的长度s。
    第2行是可取出的长度为s 的递增子序列个数。
    第3行是允许在取出的序列中多次使用x1和xn时可取出的长度为s 的递增子序列个数。

    Sample Input

    4
    3 6 2 5

    Sample Output

    2
    2
    3

    一开始自己想了个很鬼的模型30分,后来分析完全是错的。
    我那个模型并没有求最大流,只是在残余网络上找路径,所以不能保证答案是最大的。
    先DP求出以每个点的为起点的最长不下降序列长度,以为f[i];
    注意是最长不下降,这题题面与数据不符合(坑了我1个小时)
    将一个点一分为二,分为A部和B部。
    Ai和Bi连一条容量为1的边。
    f[i]==MAX
    ->Ai,f[i]==1
    Bi->T。
    枚举i后面的j,若a[i]<=a[j]
    f[j]+1==f[i],
    Bi->Aj
    然后跑最大流。
    第三问是一样的,只是把S和T连1和n还有A1B1的边,AnBn的边容量改为INF。
     1 #include<set>
     2 #include<map>
     3 #include<queue>
     4 #include<stack>
     5 #include<ctime>
     6 #include<cmath>
     7 #include<string>
     8 #include<vector>
     9 #include<cstdio>
    10 #include<cstdlib>
    11 #include<cstring>
    12 #include<iostream>
    13 #include<algorithm>
    14 using namespace std;
    15 struct data{
    16   int nex,to,w;
    17 }e[530000],g[530000];
    18 int head[1010],edge=-1,a[510],lev[1010],f[510],n;
    19 void add(int from,int to,int w){
    20   g[++edge].nex=head[from];
    21   g[edge].w=w;
    22   g[edge].to=to;
    23   head[from]=edge;
    24 }
    25 bool bfs(int s,int t){
    26   memset(lev,0,sizeof(lev));
    27   queue<int>q;
    28   q.push(s);lev[s]=1;
    29   while(!q.empty()){
    30     int u=q.front();
    31     q.pop();
    32     for(int i=head[u];i!=-1;i=e[i].nex)
    33       if(!lev[e[i].to] && e[i].w>0){
    34     lev[e[i].to]=lev[u]+1;
    35     q.push(e[i].to);
    36     if(e[i].to==t)return 1;
    37       }
    38   }
    39   return 0;
    40 }
    41 int dfs(int s,int t,int k){
    42   if(s==t) return k;
    43   int tag=0;
    44   for(int i=head[s];i!=-1;i=e[i].nex)
    45     if(e[i].w>0 && lev[e[i].to]==lev[s]+1){
    46       int d=dfs(e[i].to,t,min(k-tag,e[i].w));
    47       e[i].w-=d;
    48       e[i^1].w+=d;
    49       tag+=d;
    50       if(tag==k) return tag;
    51     }
    52   return tag;
    53 }
    54 void dinic(int s,int t){
    55   int flow=0;
    56   while(bfs(s,t)) flow+=dfs(s,t,1999999999);
    57   printf("%d
    ",flow);
    58 }
    59 int zd=0;
    60 void DP(){
    61   for(int i=1;i<=n;i++)
    62     f[i]=1;
    63   for(int i=n;i>=1;i--)
    64     for(int j=i+1;j<=n;j++)
    65       if(a[j]>=a[i]) f[i]=max(f[i],f[j]+1);
    66   for(int i=1;i<=n;i++)
    67     zd=max(zd,f[i]);
    68   printf("%d
    ",zd);
    69 }
    70 int main()
    71 {
    72   freopen("!.in","r",stdin);
    73   freopen("!.out","w",stdout);
    74   memset(head,-1,sizeof(head));
    75   bool f1=0,f2=0;
    76   scanf("%d",&n);
    77   int s=0,t=2*n+1;
    78   for(int i=1;i<=n;i++)
    79     scanf("%d",&a[i]);
    80   DP();
    81   if(zd==1) {printf("%d
    %d
    ",n,n);return 0;}
    82   for(int i=1;i<=n;i++) add(i,i+n,1),add(i+n,i,0);
    83   for(int i=1;i<=n;i++){
    84     if(f[i]==zd){if(i==1) f1=1;add(s,i,1),add(i,s,0);}
    85     if(f[i]==1) {if(i==n) f2=1;add(i+n,t,1),add(t,i+n,0);}
    86   }
    87   for(int i=1;i<=n;i++)
    88     for(int j=i+1;j<=n;j++)
    89       if(a[j]>=a[i] && f[j]+1==f[i]) add(i+n,j,1),add(j,i+n,0);
    90   memcpy(e,g,sizeof(e));
    91   dinic(s,t);
    92   if(f1) add(s,1,1999999999),add(1,s,0);
    93   if(f2) add(2*n,t,1999999999),add(t,2*n,0);
    94   add(1,n+1,1999999999),add(n+1,1,0);
    95   add(n,2*n,1999999999),add(2*n,n,0);
    96   memcpy(e,g,sizeof(e));
    97   dinic(s,t);
    98   return 0;
    99 }
    
    
    
     
  • 相关阅读:
    avrdude: stk500_getsync(): not in sync: resp=0x00
    PCB封装技术
    C/C++基础问题归集
    mf210v 端口的映射
    alsamixer 在音频子系统的使用
    rp2836 网卡以及串口与接插件位置关系
    RP2837 IN1-IN2 对应关系 2路DI
    RP2837 OUT1-OUT2 对应关系 2路DO
    RP2836 板卡信息标识
    RP2836 OUT0-OUT7 对应关系
  • 原文地址:https://www.cnblogs.com/pantakill/p/6613476.html
Copyright © 2011-2022 走看看