求助,未过样例

P2766 最长不下降子序列问题

Thunder_S @ 2022-01-16 10:57:48

#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 505
#define inf 123456789
using namespace std;
struct node
{
    int to,next,flow;
}a[N<<2];
queue<int> q;
int n,ans,S,T,tot=1,val[N],f[N],head[N<<1],cur[N<<1],dep[N<<1];
void add(int x,int y,int z)
{
    a[++tot].to=y;a[tot].flow=z;a[tot].next=head[x];head[x]=tot;
    a[++tot].to=x;a[tot].flow=0;a[tot].next=head[y];head[y]=tot;
}
bool bfs()
{
    memset(dep,0,sizeof(dep));
    while (!q.empty()) q.pop();
    q.push(S);
    dep[S]=1;
    while (!q.empty())
    {
        int x=q.front();q.pop();
        if (x==T) return true;
        for (int i=head[x];i;i=a[i].next)
        {
            int y=a[i].to;
            if (!dep[y]&&a[i].flow)
            {
                dep[y]=dep[x]+1;
                q.push(y);
            }
        }
    }
    return false;
}
int dfs(int now,int flow)
{
    if (now==T) return flow;
    int res=0;
    for (int &i=cur[now];i;i=a[i].next)
    {
        int v=a[i].to;
        if (a[i].flow&&dep[v]==dep[now]+1)
        {
            int fl=dfs(v,min(a[i].flow,flow));
            // if (!fl) continue;
            // a[i].flow-=fl;a[i^1].flow+=fl;
            // res+=fl;flow-=fl;
            // if (!flow) break;
            if (fl)
            {
                a[i].flow-=fl;
                a[i^1].flow+=fl;
                return fl;
            }
        }
    }
    // return res;
    return 0;
}
int dinic()
{
    int res=0;
    while (bfs())
    {
        for (int i=1;i<=2*n+2;++i)
            cur[i]=head[i];
        res+=dfs(S,inf);
    }
    return res;
}
int main()
{
    scanf("%d",&n);
    for (int i=1;i<=n;++i)
        scanf("%d",&val[i]);
    for (int i=n;i;--i)
    {
        f[i]=1;
        for (int j=n;j>i;--j)
            if (val[j]>=val[i]) f[i]=max(f[i],f[j]+1);
        ans=max(ans,f[i]);
    }
    printf("%d\n",ans);
    S=2*n+1;T=2*n+2;
    for (int i=1;i<=n;++i)
        if (f[i]==ans) add(S,i,1);
    for (int i=1;i<=n;++i)
        if (f[i]==1) add(i+n,T,1);
    for (int i=1;i<=n;++i)
        add(i,i+n,1);
    for (int i=1;i<=n;++i)
        for (int j=i+1;j<=n;++j)
            if (val[j]>val[i]&&f[i]==f[j]+1) add(i+n,j,1);
    printf("%d\n",dinic());
    tot=1;
    memset(head,0,sizeof(head));
    for (int i=1;i<=n;++i)
        if (f[i]==ans) 
        {
            if (i!=1) add(S,i,1);
            else add(S,i,inf);
        }
    for (int i=1;i<=n;++i)
        if (f[i]==1) 
        {
            if (i!=n) add(i+n,T,1); 
            else add(i+n,T,inf);
        }
    for (int i=1;i<=n;++i)
        add(i,i+n,1);
    for (int i=1;i<=n;++i)
        for (int j=i+1;j<=n;++j)
            if (val[j]>val[i]&&f[i]==f[j]+1) add(i+n,j,1);
    printf("%d\n",dinic());
    return 0;
}

by Thunder_S @ 2022-01-16 10:58:02

第 3 问输出 2.


|