• [网络流24题]最长递增子序列问题 最大流


    给定正整数序列x1 ,... , xn 。 (1)计算其最长递增子序列的长度s。(严格递增) (2)计算从给定的序列中最多可取出多少个长度为s的递增子序列。 (3)如果允许在取出的序列中多次使用x1和xn,则从给定序列中最多可取出多少个长 度为s的递增子序列。 编程任务: 设计有效算法完成(1)(2)(3)提出的计算任务。
    由文件input.txt提供输入数据。文件第1 行有1个正整数n(n<400),表示给定序列的长度。接 下来的1 行有n个正整数 x1 , ... , xn。
    程序运行结束时,将任务(1)(2)(3)的解答输出到文件output.txt中。第1 行是最长 递增子序列的长度s。第2行是可取出的长度为s 的递增子序列个数。第3行是允许在取出 的序列中多次使用x1和xn时可取出的长度为s 的递增子序列个数。

    Sample Input

    4 3 6 2 5

    Sample Output

    2 2 3
     
    题解:
    1.第一问直接DP
    2.拆点,(i,i+n,1).
    if(F[i]==ans)init(i+n,T,1);
    if(F[i]==1)init(S,i,1).
    3.把S-i i-i+n n+n-T n-n+n的容量改为正无穷即可
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int N=1005,INF=1999999999;
    int gi(){
        int str=0;char ch=getchar();
        while(ch>'9'||ch<'0')ch=getchar();
        while(ch>='0' && ch<='9')str=str*10+ch-48,ch=getchar();
        return str;
    }
    int n,s[N],F[N],ans,S=0,T;
    int head[N],num=1;
    struct Lin{
        int next,to,dis;
    }a[N*N*4];
    void init(int x,int y,int z){
        a[++num].next=head[x];
        a[num].to=y;
        a[num].dis=z;
        head[x]=num;
        a[++num].next=head[y];
        a[num].to=x;
        a[num].dis=0;
        head[y]=num;
    }
    int dep[N],q[N];
    bool bfs()
    {
        memset(dep,0,sizeof(dep));
        int x,u,t=0,sum=1;
        dep[S]=1;q[1]=S;
        while(t!=sum)
        {
            x=q[++t];
            for(int i=head[x];i;i=a[i].next){
                u=a[i].to;
                if(a[i].dis<=0 || dep[u])continue;
                dep[u]=dep[x]+1;q[++sum]=u;
            }
        }
        return dep[T];
    }
    int dfs(int x,int flow)
    {
        if(x==T || !flow)return flow;
        int u,tmp,sum=0;
        for(int i=head[x];i;i=a[i].next){
            u=a[i].to;
            if(a[i].dis<=0 || dep[u]!=dep[x]+1)continue;
            tmp=dfs(u,flow<a[i].dis?flow:a[i].dis);
            a[i].dis-=tmp;a[i^1].dis+=tmp;
            flow-=tmp;sum+=tmp;
            if(!flow)break;
        }
        return sum;
    }
    int maxflow()
    {
        int tot=0,tmp;
        while(bfs()){
            tmp=dfs(S,INF);
            while(tmp)tot+=tmp,tmp=dfs(S,INF);
        }
        return tot;
    }
    void Clear(){
        memset(head,0,sizeof(head));
        num=1;
    }
    int main()
    {
        n=gi();T=(n<<1)+1;
        for(int i=1;i<=n;i++)s[i]=gi(),F[i]=1;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<i;j++)if(s[i]>s[j] && F[j]+1>F[i])F[i]=F[j]+1;
            if(F[i]>ans)ans=F[i];
        }
        printf("%d
    ",ans);
        for(int i=1;i<=n;i++)
        {
            init(i,i+n,1);
            if(F[i]==ans)init(i+n,T,1);
            if(F[i]==1)init(S,i,1);
            for(int j=1;j<i;j++)
            {
                if(s[i]>s[j] && F[j]+1==F[i])init(j+n,i,1);
            }
        }
        printf("%d
    ",maxflow());
        Clear();
        for(int i=1;i<=n;i++)
        {
            init(i,i+n,1);
            if(F[i]==ans)init(i+n,T,1);
            if(F[i]==1)init(S,i,1);
            for(int j=1;j<i;j++)
            {
                if(s[i]>s[j] && F[j]+1==F[i])init(j+n,i,1);
            }
        }
        if(F[n]==ans)init(n+n,T,INF);
        init(1,1+n,INF);init(S,1,INF);init(n,n+n,INF);
        printf("%d",maxflow());
        return 0;
    }
  • 相关阅读:
    Rabbitmq 性能测试
    B+树图文详解
    图的概念和存储(邻接矩阵,邻接表)
    WebApi系列文章
    Asp.Net MVC项目集成Swagger
    正则表达式匹配两个特殊字符中间的内容
    数学常数e的含义
    十大排序算法总结
    C#集合类型大揭秘
    深入System.Web.Caching命名空间 教你Hold住缓存管理(三)
  • 原文地址:https://www.cnblogs.com/Yuzao/p/6915560.html
Copyright © 2020-2023  润新知