hdu 3998 dp+最大流

来源:互联网 发布:淘宝男装代理 编辑:程序博客网 时间:2024/06/05 18:09

Sequence

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1164    Accepted Submission(s): 421


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
43 6 2 5
 

Sample Output
22

题意:求最长上升子序列的长度以及个数。

解题思路:先求最长上升子序列,

然后添加一个源点,一个汇点,对每个点拆点,假如dp[i]=1那么从源点向i连流量为1,的边,如果dp[i]=k从i+n向汇点连流量为1的边,如果i<j,且dp[i]+1=dp[j],则连边,

然后最大流。

代码:

#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <set>#include <map>#include <string>#include <math.h>#include <stdlib.h>#include <time.h>using namespace std;#define inf 0x3f3f3f3fconst int maxn=10000;int head[maxn],tol,dep[maxn],n;struct node{       int next,to,from,cap;}edge[300000];void add(int u,int v,int cap){       edge[tol].from=u;       edge[tol].to=v;       edge[tol].cap=cap;       edge[tol].next=head[u];       head[u]=tol++;       edge[tol].from=v;       edge[tol].to=u;       edge[tol].cap=0;       edge[tol].next=head[v];       head[v]=tol++;}int bfs(int s,int t){       int que[maxn],front=0,rear=0;       memset(dep,-1,sizeof(dep));       dep[s]=0;que[rear++]=s;       while(front!=rear)       {              int u=que[front++];front%=maxn;              for(int i=head[u];i!=-1;i=edge[i].next)              {                     int v=edge[i].to;                     if(edge[i].cap>0&&dep[v]==-1)                     {                            dep[v]=dep[u]+1;                            que[rear++]=v;                            rear%=maxn;                            if(v==t)return 1;                     }              }       }       return 0;}int dinic(int s,int t){       int i,res=0,top;       int Stack[maxn],cur[maxn];       while(bfs(s,t))       {              memcpy(cur,head,sizeof(head));              int u=s;top=0;              while(1)              {                     if(u==t)                     {                            int min=inf,loc;                            for(int i=0;i<top;i++)                            if(min>edge[Stack[i]].cap)                            {                                   min=edge[Stack[i]].cap;                                   loc=i;                            }                            for(int i=0;i<top;i++)                            {                                   edge[Stack[i]].cap-=min;                                   edge[Stack[i]^1].cap+=min;                            }                            res+=min;                            top=loc;                            u=edge[Stack[top]].from;                     }                     for(int i=cur[u];i!=-1;cur[u]=i=edge[i].next)                     if(edge[i].cap&&dep[u]+1==dep[edge[i].to])break;                     if(cur[u]!=-1)                     {                            Stack[top++]=cur[u];                            u=edge[cur[u]].to;                     }                     else                     {                            if(top==0)break;                            dep[u]=-1;                            u=edge[Stack[--top]].from;                     }              }       }       return res;}int a[30000],dp[30000];int main(){    //  freopen("data.in","r",stdin);     // freopen("data.out","w",stdout);      int i,j,k,m,n;      while(~scanf("%d",&n))      {     memset(head,-1,sizeof(head));tol=0;         for(i=1;i<=n;i++)scanf("%d",&a[i]);     int  ans=0;     for(i=1;i<=n;i++)     {    dp[i]=1;    for(j=1;j<i;j++)   if(a[j]<a[i]&&dp[j]>=dp[i])  dp[i]=dp[j]+1;    ans=max(ans,dp[i]);     }    // for(i=1;i<=n;i++)cout<<dp[i]<<" ";cout<<endl;   // cout<<ans<<endl;     for(i=1;i<=n;i++)     {    add(i,i+n,1);    if(dp[i]==1)add(0,i,1);     if(dp[i]==ans)add(i+n,2*n+1,1);    for(j=i+1;j<=n;j++)   if(dp[j]==dp[i]+1)  add(i+n,j,1);     }    // cout<<tol<<endl;     int flow=dinic(0,2*n+1);     //if(flow==0)flow++;     printf("%d\n%d\n",ans,flow);      }      return 0;}


0 0
原创粉丝点击