https://www.luogu.org/problemnew/show/P2766

题解:网络流+最大流+DP

首先动态规划求出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)这四条边的容量修改为无穷大,再求一次网络最大流,就是第三问结果。

上述建模方法是应用了一种分层图的思想,把图每个顶点i按照F[i]的不同分为了若干层,这样图中从S出发到T的任何一条路径都是一个满足条件的最长上升子序列。

由于序列中每个点要不可重复地取出,需要把每个点拆分成两个点。单位网络的最大流就是增广路的条数,所以最大流量就是第二问结果。

第三问特殊地要求x1和xn可以重复使用,只需取消这两个点相关边的流量限制,求网络最大流即可。

/*
*@Author:   STZG
*@Language: C++
*/
#include <bits/stdc++.h>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<string>
#include<vector>
#include<bitset>
#include<queue>
#include<deque>
#include<stack>
#include<cmath>
#include<list>
#include<map>
#include<set>
//#define DEBUG
#define RI register int
#define endl "\n"
using namespace std;
typedef long long ll;
//typedef __int128 lll;
const int N=1000+10;
const int M=100000+10;
const int MOD=1e9+7;
const double PI = acos(-1.0);
const double EXP = 1E-8;
const int INF = 0x3f3f3f3f;
int s,t,n,m,k,p,l,r,u,v;
int ans,cnt,flag,temp,sum,maxflow,len;
int a[N];
int dis[N];
int dp[N];
struct node{int u,v;ll c;node(){};node(int u,int v,ll cap):u(u),v(v),c(cap){}
};
vector<node>edge;
vector<int>G[N];
void Addedge(int u,int v,ll cap){edge.push_back({u,v,cap});edge.push_back({v,u,0});int sz=edge.size();G[u].push_back(sz-2);G[v].push_back(sz-1);
}
bool bfs(int u){memset(dis,-1,sizeof(dis));dis[u]=0;queue<int>q;q.push(u);while(!q.empty()){int u=q.front();q.pop();for(int i=0,j=G[u].size();i<j;i++){node e=edge[G[u][i]];if(dis[e.v]<0&&e.c>0){dis[e.v]=dis[u]+1;q.push(e.v);}}}return dis[t]>0;
}
ll dfs(int u,ll flow){if(u==t){return flow;}ll now;for(int i=0,j=G[u].size();i<j;i++){node e=edge[G[u][i]];if(e.c>0&&dis[e.v]==dis[u]+1&&(now=dfs(e.v,min(flow,e.c)))){edge[G[u][i]].c-=now;edge[G[u][i]^1].c+=now;return now;}}return 0;
}
void dinic(){ll res;while(bfs(s)){while((res=dfs(s,INF))){ans+=res;}}
}
void init(){s=0;t=2*n+1;edge.clear();for(int i=s;i<=t;i++)G[i].clear();ans=0;maxflow=0;len=0;
}
int main()
{
#ifdef DEBUGfreopen("input.in", "r", stdin);//freopen("output.out", "w", stdout);
#endif//ios::sync_with_stdio(false);//cin.tie(0);//cout.tie(0);//scanf("%d",&t);//while(t--){while(~scanf("%d",&n)){for(int i=1;i<=n;i++){scanf("%d",&a[i]);dp[i]=1;}init();for(int i=1;i<=n;i++)for(int j=1;j<i;j++)if(a[j]<=a[i])dp[i]=max(dp[i],dp[j]+1);for(int i=1;i<=n;i++)len=max(len,dp[i]);cout<<len<<endl;for(int i=1;i<=n;i++)if(dp[i]==1)Addedge(s,i,1);for(int i=1;i<=n;i++)if(dp[i]==len)Addedge(i+n,t,1);for(int i=1;i<=n;i++)Addedge(i,i+n,1);for(int i=1;i<=n;i++)for(int j=1;j<i;j++)if(a[j]<=a[i]&&dp[j]+1==dp[i])Addedge(j+n,i,1);dinic();cout<<ans<<endl;Addedge(1,1+n,INF);Addedge(s,1,INF);if(dp[n]==len)Addedge(n,n*2,INF),Addedge(n*2,t,INF);dinic();cout<<ans<<endl;}//}#ifdef DEBUGprintf("Time cost : %lf s\n",(double)clock()/CLOCKS_PER_SEC);
#endif//cout << "Hello world!" << endl;return 0;
}

最长不下降子序列问题相关推荐

  1. 最长不下降子序列(推广问题)

    最长不下降子序列问题的定义:在一个序列中,找到一个最长的子序列,其中这个序列是非递减的 我们可以把这个非递减推广,其实非递减就是一种顺序,那么我们可以把定义推广到:给出一个顺序序列.目标序列中,在目标 ...

  2. 最大流 ---- 最大不相交路径数 ---- P2766 最长不下降子序列问题(网络流24题)

    题目链接 最多不相交路径 这种问题变化比较多,但都能表示成以下形式: 已知一些路径,每个节点只能属于一条路径,求能选择多少条路径使它们不相交. 主要的方法是拆点,将一个点拆成两个,然后连边,容量表示该 ...

  3. 最长不下降子序列java代码_浅谈最长不下降子序列与最长上升子序列

    唔,最长不下降子序列与最长上升子序列曾是困扰蒟蒻多时的一个问题,应该也有一些人分不清这2个的求法吧. 首先n^2算法肯定是都能分清的,因为不下降和上升的区别是连续的2个能不能相等,只需要在判断的时候判 ...

  4. 【P2766】 最长不下降子序列问题

    题目描述 «问题描述: 给定正整数序列x1,...,xn . (1)计算其最长不下降子序列的长度s. (2)计算从给定的序列中最多可取出多少个长度为s的不下降子序列. (3)如果允许在取出的序列中多次 ...

  5. 最长不下降子序列的O(n^2)算法和O(nlogn)算法

    转帖 最长不下降子序列的O(n^2)算法和O(nlogn)算法 最长不下降子序列(LIS:Longest Increasing Subsequence) //用句通俗的话说,我讲的很通俗易懂~~ 问题 ...

  6. 洛谷2766:[网络流24题]最长不下降子序列问题——题解

    https://www.luogu.org/problemnew/show/P2766 给定正整数序列x1,...,xn . (1)计算其最长不下降子序列的长度s. (2)计算从给定的序列中最多可取出 ...

  7. CodeForces - 1437E Make It Increasing(确定首尾的最长不下降子序列)

    题目链接:点击查看 题目大意:给出一个长度为 n 的序列,现在有 m 个位置被锁定,也就是无法进行操作,每次操作可以选择一个没有被锁定的位置,将其更改为任意数值,现在问最少进行多少次操作,可以使得整个 ...

  8. 洛谷 - P2766 最长不下降子序列问题(最大流+动态规划+思维建边)

    题目链接:点击查看 题目大意:给出一个由n个数组成的序列,有三个子问题: 求出当前数列的最长不下降子序列的长度len 如果每个数最多只能使用一次,问最多可以组成多少个长度为len的最长不下降子序列 如 ...

  9. 中石油训练赛 - Racing Gems(最长不下降子序列)

    题目描述 You  are  playing  a  racing  game.  Your  character  starts  at  the  X-axis  line  (y=0)  and ...

  10. HDU - 1160 FatMouse's Speed(最长不下降子序列)

    题目链接:点击查看 题目大意:给出许多二元组(W,S),最后要求输出最长的满足W严格递增,S严格递减的子序列长度,以及方案,输出任意一种即可 题目分析:看起来像二维偏序,其实对任意一维排序后求最长不下 ...

最新文章

  1. SAP Cloud for Customer移动端应用SAP推荐的网络时延参数
  2. 基于C#开发的浏览器隐身工具-上班别乱开
  3. 公司电脑监控软件_公司电脑监控软件,如何限制公司电脑网络游戏
  4. 小强升职记梗概_时间管理法 ——《小强升职记》读书笔记 1
  5. Linux搭建深度学习环境使用指南
  6. pip install flask-mongoengine报错
  7. 在页面显示html文件,把选择的文件显示在页面上 #1《 HTML5:文件 API 》
  8. Linux内核开发之异步通知与异步I/O《来自linux设备开发详解》
  9. iview表单校验上传图片成功后,提示文字不消失
  10. WAVE族函数的使用
  11. sql服务器注册表被禁用,彻底删除SQL Server注册表信息
  12. 什么是PPI,有什么作用?
  13. python去除图片水印api,python去除图片水印(部分可)
  14. 【历史上的今天】4 月 18 日:第一款交互式电子游戏;IBM 率先研发兆位芯片;硬件公司 Roland 成立
  15. 8分钟带你彻底弄懂《信号与系统》
  16. SpringBoot 在main或者普通类中条用service接口
  17. ecshop管理找不到index.php,运行initFecShop脚本时报错:文件environments/index.php找不到...
  18. (C/C++)图形界面库EasyX库(graphics.h)的下载与安装
  19. 在电脑上哪儿看提高收视率_电视上收视率最高的电影的网上搜集完整指南
  20. 天猫延迟发货的定义是什么?延迟发货商家如何赔付?

热门文章

  1. java max sum_杭电1024 Max Sum Plus Plus状压dp(java)
  2. 如何处理高并发写入mysql_如何处理高并发情况下的DB插入
  3. html 自定义标签解析,Java解析Html自定义标签的属性
  4. c语言中的字符变量用保留字()来说明,C语言程序设计填空题2
  5. zk服务器系统,windows系统搭建zookeeper服务器的教程
  6. java http请求
  7. 浅谈equals和==的区别
  8. 1 搭建MyBatis环境
  9. python关联分析引擎_PowerBI x Python 之关联分析(上)
  10. 八、Flume的构架,安装和基本使用