[cogs731] [网络流24题#6] 最长递增子序列 [网络流,最大流]
【转hzwer】第一问是LIS,动态规划求解,第二问和第三问用网络最大流解决。首先动态规划求出F[i],表示以第i位为开头的最长上升序列的长度,求出最长上升序列长度K。1、把序列每位i拆成两个点<i.a>和<i.b>,从<i.a>到<i.b>连接一条容量为1的有向边。2、建立附加源S和汇T,如果序列第i位有F[i]=K,从S到<i.a>连接一条容量为1的有向边。3、如果F[i]=1,从<i.b>到T连接一条容量为1的有向边。4、如果j>i且A[i] < A[j]且F[j]+1=F[i],从<i.b>到<j.a>连接一条容量1的有向边。求网络最大流,就是第二问的结果。把边(<1.a>,<1.b>)(<N.a>,<N.b>)(S,<1.a>)(<N.b>,T)这四条边的容量修改为无穷大,再求一次网络最大流,就是第三问结果。利用动规求解网络流问题。
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <vector> using namespace std; #define Debug template<const int _n,const int _m>
struct Edge
{
struct Edge_base { int to,next,w; }e[_m]; int cnt,p[_n];
Edge() { clear(); }
void insert(const int x,const int y,const int z)
{ e[++cnt].to=y; e[cnt].next=p[x]; e[cnt].w=z; p[x]=cnt; return ; }
int start(const int x) { return p[x]; }
void clear() { cnt=,memset(p,,sizeof(p)); }
Edge_base& operator[](const int x) { return e[x]; }
}; Edge<,> e;
int Ans=,tAns;
int n,a[],cur[],level[],SSS,TTT;
int f[]; bool Bfs(const int S)
{
int i,t;
queue<int> Q;
memset(level,,sizeof(level));
level[S]=;
Q.push(S);
while(!Q.empty())
{
t=Q.front(),Q.pop();
for(i=e.start(t);i;i=e[i].next)
{
if(!level[e[i].to] && e[i].w)
{
level[e[i].to]=level[t]+;
Q.push(e[i].to);
}
}
}
return level[TTT];
} int Dfs(const int S,const int bk)
{
if(S==TTT)return bk;
int rest=bk;
for(int &i=cur[S];i;i=e[i].next)
{
if(level[e[i].to]==level[S]+ && e[i].w)
{
int flow=Dfs(e[i].to,min(rest,e[i].w));
e[i].w-=flow;
e[i^].w+=flow;
if((rest-=flow)<=)break;
}
}
if(rest==bk)level[S]=;
return bk-rest;
} int Dinic()
{
int flow=;
while(Bfs(SSS))
{
memcpy(cur,e.p,sizeof(cur));
flow+=Dfs(SSS,0x3f3f3f3f);
}
return flow;
} void Calc1()
{
int i,j; for(i=;i<=n;++i)
{
if(f[i]==)e.insert(SSS,i,),e.insert(i,SSS,);
if(f[i]==Ans)e.insert(i+n,TTT,),e.insert(TTT,i+n,);
e.insert(i,i+n,);
e.insert(i+n,i,);
}
for(i=;i<=n;++i)
{
for(j=i+;j<=n;++j)
{
if(a[j]>=a[i] && f[j]==f[i]+)
e.insert(i+n,j,),e.insert(j,i+n,);
}
}
printf("%d\n",tAns=Dinic());
} void Calc2()
{
int i,j;
e.clear();
for(i=;i<=n;++i)
{
int v=;
if(i== || i==n)v=0x3f3f3f3f;
if(f[i]==)e.insert(SSS,i,v),e.insert(i,SSS,);
if(f[i]==Ans)e.insert(i+n,TTT,v),e.insert(TTT,i+n,);
e.insert(i,i+n,v);
e.insert(i+n,i,);
}
for(i=;i<=n;++i)
{
for(j=i+;j<=n;++j)
{
if(a[j]>=a[i] && f[j]==f[i]+)
e.insert(i+n,j,),e.insert(j,i+n,);
}
}
int temp=Dinic();
if(temp>=0x3f3f3f3f)temp=tAns;
printf("%d\n",temp);
return ;
} int main()
{
freopen("alis.in","r",stdin);
freopen("alis.out","w",stdout); int i,j; scanf("%d",&n);
for(i=;i<=n;++i)scanf("%d",&a[i]); for(i=;i<=n;++i)
{
f[i]=;
for(j=;j<i;++j)
if(a[j]<=a[i])f[i]=max(f[i],f[j]+);
Ans=max(Ans,f[i]);
} printf("%d\n",Ans); SSS=n<<|,TTT=SSS+;
Calc1();
Calc2(); return ;
}
[cogs731] [网络流24题#6] 最长递增子序列 [网络流,最大流]的更多相关文章
- Libre 6005 「网络流 24 题」最长递增子序列 / Luogu 2766 最长递增子序列问题(网络流,最大流)
Libre 6005 「网络流 24 题」最长递增子序列 / Luogu 2766 最长递增子序列问题(网络流,最大流) Description 问题描述: 给定正整数序列x1,...,xn . (1 ...
- 【刷题】LOJ 6005 「网络流 24 题」最长递增子序列
题目描述 给定正整数序列 \(x_1 \sim x_n\) ,以下递增子序列均为非严格递增. 计算其最长递增子序列的长度 \(s\) . 计算从给定的序列中最多可取出多少个长度为 \(s\) 的递增子 ...
- 【PowerOJ1741&网络流24题】最长递增子序列问题(最大流)
题意: 思路: [问题分析] 第一问时LIS,动态规划求解,第二问和第三问用网络最大流解决. [建模方法] 首先动态规划求出F[i],表示以第i位为开头的最长上升序列的长度,求出最长上升序列长度K. ...
- 【网络流24题】最长k可重线段集(费用流)
[网络流24题]最长k可重线段集(费用流) 题面 Cogs的数据有问题 Loj 洛谷 题解 这道题和最长k可重区间集没有区别 只不过费用额外计算一下 但是,还是有一点要注意的地方 这里可以是一条垂直的 ...
- 【网络流24题】最长k可重区间集(费用流)
[网络流24题]最长k可重区间集(费用流) 题面 Cogs Loj 洛谷 题解 首先注意一下 这道题目里面 在Cogs上直接做就行了 洛谷和Loj上需要判断数据合法,如果\(l>r\)就要交换\ ...
- LibreOJ #6014. 「网络流 24 题」最长 k 可重区间集
#6014. 「网络流 24 题」最长 k 可重区间集 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据 ...
- 【刷题】LOJ 6227 「网络流 24 题」最长k可重线段集问题
题目描述 给定平面 \(\text{xoy}\) 上 \(n\) 个开线段组成的集合 \(\text{I}\) ,和一个正整数 \(k\) ,试设计一个算法. 从开线段集合 \(\text{I}\) ...
- loj #6014. 「网络流 24 题」最长 k 可重区间集
#6014. 「网络流 24 题」最长 k 可重区间集 题目描述 给定实直线 L LL 上 n nn 个开区间组成的集合 I II,和一个正整数 k kk,试设计一个算法,从开区间集合 I II 中选 ...
- 【网络流24题】最长k可重区间集问题(费用流)
[网络流24题]最长k可重区间集问题 [问题分析] 最大权不相交路径问题,可以用最大费用最大流解决. [建模方法] 方法1 按左端点排序所有区间,把每个区间拆分看做两个顶点<i.a>< ...
随机推荐
- 利用【监听器】动态加载Log4j配置文件
转自:https://veromca273.iteye.com/blog/1889304 1 创建监听器: public class LogListener implements ServletCon ...
- 客户端JavaScript基础 网页上的输入输出
创建: 2017/10/06 完成: 2017/10/07 更新: 2017/10/15 增加了通过事件监听器登陆事件的方法的链接 # TODO: 补充 基于Canvas的图象 客户端Java ...
- 解决UTF-8方法归纳
1:通过spring配置过滤器解决 <!-- 配置Spring提供的字符编码过滤器 --> <filter> <filter-name>SpringCharacte ...
- poi导出excel改变标题颜色
在excelutil类里面添加 public class ExcelUtil { public static Workbook fillExcelData(ResultSet rs, Workbook ...
- linux命令(001) -- chkconfig
一.准备知识 在说明chkconfig命令的用途之前,有必要先了解一下Linux系统中/etc/rc[0-6].d目录的用途. 众所周知,在Linux系统定义了7种不同的启动级别,这7种启动级别的含义 ...
- MVC系列学习(十七)-过滤器
本次学习的文件结构如下 1.过滤器的几种表示方式 1.1将过滤器 加到方法上,作用范围为该方法 1.2将过滤器加到当前类上,作用范围为该类的所有方法 1.3添加全局过滤器,作用范围为所有方法 2.Ac ...
- O-理解共享池
我们可以通过show sga命令查看共享池的整体组成部分: ....待截图.... 一.SGA内存结构 Oracle中SGA主要包括: 1.固定数据结构部分(FIXED Size) 2.数据块缓冲区( ...
- 使用NSSM将Kibana安装为Windows服务
Kibana不同于Elasticsearch,前者官方并没有提供安装为系统服务的方法,如果直接运行在生产环境中会尤为麻烦,一旦服务器因故重启就要手动开启,所以将Kibana安装为系统服务非常有必要. ...
- CAD在网页绘一个直线,得到直线id,再调该得到直线对象,然写扩展数据
IMxDrawDatabase::ObjectIdToObject 实体id返回实体对象. 参数 说明 [in] LONGLONG lId 实体id JS代码,中绘一个直线,得到直线id,再调该得到直 ...
- 程序员不可不知的Linux性能工具
前言 在实际开发中,有时候会收到一些服务的监控报警,比如CPU飙高,内存飙高等,这个时候,我们会登录到服务器上进行排查.本篇博客将涵盖这方面的知识:Linux性能工具. 一次线上问题排查模拟 背景:服 ...