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).
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.
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
- hdu 3998 (dp+最大流)
- hdu 3998 dp+最大流
- hdu 3998(DP+最大流)
- hdu 3998 Sequence(最大流+dp)
- HDU 3998 Sequence 最大流 isap 加 dp
- hdu 3998 Sequence【dp+拆点+最大流--------Dinic】
- hdu 3998 Sequence(DP+最大流,求最多的不相交路径)
- hdu 2686 Matrix - 最小费用最大流 或 多线程DP
- hdu 2686 Matrix(最大费用流||多线程DP)@
- Hdu 最大连续子序列(DP)
- Hdu 最大报销额(DP)
- hdu 1559【最大子矩阵和DP】
- hdu 1003(最大子序列 DP)
- hdu 1231 最大连续子序列(DP)
- HDU 1231 最大连续子序列 (dp)
- hdu 1864 最大报销额 【DP】
- hdu 1231最大连续子序列 【DP】
- hdu 1506 最大长方形 不错的DP
- Matlab--最短路问题
- erlang -- timeout 的简单使用
- 数据结构与算法2:八皇后问题
- cocos2dx之场景特效
- linux下编写RTC驱动
- hdu 3998 dp+最大流
- Lua 解释器程序
- HDU3795-最短路径问题-Dijkstra算法
- 能让土豆能自动播放的代码 --- &autoPlay=true
- 查找与排序:利用基数排序对0~100范围内数据实现排序
- sgu157 Patience DFS打表
- Lua 类型与值
- 处事心得
- 【数学基础】多个数的最大公约数