网络流二十四题之六 —— 最长不下降子序列问题(ALIS)
2016-05-12 13:32
543 查看
最长不下降子序列问题
Description
给定正整数序列 x1,…,xn 。(1)计算其最长不下降子序列的长度 s。
(2)计算从给定的序列中最多可取出多少个长度为 s 的不下降子序列。
(3)如果允许在取出的序列中多次使用 x1 和 xn,则从给定序列中最多可取出多少个长
度为 s 的不下降子序列。
Input
文件第 1 行有 1 个正整数 n,表示给定序列的长度。接下来的 1 行有 n 个正整数 x1,…,xn 。
Output
程序运行结束时,将任务(1)(2)(3)的解答输出。第 1 行是最长不下降子序列的长度 s。
第 2 行是可取出的长度为 s 的不下降子序列个数。
第 3 行是允许在取出的序列中多次使用 x1 和 xn 时可取出的长度为 s 的不下降子序列个数。
Sample Input
43 6 2 5
Sample Output
22
3
Solution
第一问用动态规划。因为数据规模不大,O(n2) 可以过。第二问用网络流。
若存在 j>i,并且 fj=fi+1(fi 表示以 i 为结束的最长不下降子序列的长度),那么将 i 与 j 连一条边。
连接 i 与 s,当 fi=1。
连接 i 与 t,当 fi=ans1。
求最大流即可。
第三问,将第一个点和最后一个点连的边的权值设为 ∞ 即可。
Code
[cpp] #include <iostream>#include <cstdio>
#include <cstring>
#include <queue>
#define Max(x,y) ((x)>(y)?(x):(y))
#define Min(x,y) ((x)<(y)?(x):(y))
#define ss 0
#define tt 900
#define INF 0x3f3f3f3f
using namespace std;
int n,ans1,cnt;
int s[1000];
int f[1000];
int head[1000];
int nxt[1000010];
int data[1000010];
int flow[1000010];
int dis[1000];
queue<int>q;
void add(int x,int y,int z){
nxt[cnt]=head[x];data[cnt]=y;flow[cnt]=z;head[x]=cnt++;
nxt[cnt]=head[y];data[cnt]=x;flow[cnt]=0;head[y]=cnt++;
}
bool BFS(){
memset(dis,-1,sizeof dis);
dis[ss]=0;
q.push(ss);
while(!q.empty()){
int now=q.front();
q.pop();
for(int i=head[now];i!=-1;i=nxt[i]){
if(flow[i]&&dis[data[i]]==-1){
q.push(data[i]);
dis[data[i]]=dis[now]+1;
}
}
}
return dis[tt]>0;
}
int dfs(int now,int low){
if(now==tt)return low;
int Low;
for(int i=head[now];i!=-1;i=nxt[i]){
if(flow[i]&&dis[data[i]]==dis[now]+1){
if(Low=dfs(data[i],Min(low,flow[i]))){
flow[i]-=Low;
flow[i^1]+=Low;
return Low;
}
}
}
return 0;
}
int main(){
freopen(”alis.in”,“r”,stdin);
freopen(”alis.out”,“w”,stdout);
scanf(”%d”,&n);
memset(head,-1,sizeof head);
for(int i=1;i<=n;i++)scanf(“%d”,&s[i]);
f[1]=1;
for(int i=2;i<=n;i++){
f[i]=1;
for(int j=1;j<i;j++)
if(s[i]>=s[j])f[i]=Max(f[i],f[j]+1);
ans1=Max(ans1,f[i]);
}
printf(”%d\n”,ans1);
for(int i=1;i<=n;i++){
if(f[i]==1)add(ss,i,1);
if(f[i]==ans1)add(i,tt,1);
for(int j=i+1;j<=n;j++)
if(f[j]==f[i]+1&&s[j]>=s[i])add(i,j,1);
}
int flag,ans2=0;
while(BFS())
while(flag=dfs(ss,INF))ans2+=flag;
printf(”%d\n”,ans2);
if(ans1==1){
printf(”%d\n”,ans2);
return 0;
}
cnt=0;
memset(head,-1,sizeof head);
memset(data,0,sizeof data);
memset(nxt,0,sizeof nxt);
memset(flow,0,sizeof flow);
for(int i=1;i<=n;i++){
if(f[i]==1){
if(i!=1&&i!=n)
add(ss,i,1);
else add(ss,i,INF);
}
if(f[i]==ans1){
if(i!=1&&i!=n)
add(i,tt,1);
else add(i,tt,INF);
}
for(int j=i+1;j<=n;j++)
if(f[j]==f[i]+1&&s[j]>=s[i]){
if(ans1==2&&i==1&&j==n){
add(i,j,1);
continue;
}
if(i==1||i==n||j==1||j==n)
add(i,j,INF);
else add(i,j,1);
}
}
int ans3=0;
while(BFS())
while(flag=dfs(ss,INF))ans3+=flag;
printf(”%d\n”,ans3);
return 0;
}
相关文章推荐
- 如何在 在SharePoint 2013/2010 解决方案中添加 ashx (HttpHandler)
- Servlet 处理HTTP请求
- HTTP 2.0
- Swift网络请求,数据模型,图片缓存,自动布局,上拉刷新下拉加载
- Http Post远程调用
- HTTP、HTTPS
- 以太网基础知识0(UDP和TCP有什么区别)
- 安卓性能优化4-1 网络缓存
- iOS网络请求动画
- Android Https相关完全解析 当OkHttp遇到Https
- 虚拟机下使用NAT模式,主机模式配置Linux 网络ip
- AFNetworking3.xPost请求- “请求对象无法序列化”处理及:App Transport Security has blocked a cleartext HTTP (http://)
- http协议
- httpClient抓取页面的简易使用
- loadrunner简单使用——HTTP,WebService,Socket压力测试脚本编写
- [原] KVM虚拟机网络闪断分析
- OkHttp2.4.0在AS上使用
- c#网络编程之TCP/IP(一)C#线程任务基础Thread
- http 错误代码表
- Hadoop学习之网络爬虫+分词+倒排索引实现搜索引擎案例