codevs1906 最长递增子序列问题
给定正整数序列x1,..... , xn 。
(1)计算其最长递增子序列的长度s。
(2)计算从给定的序列中最多可取出多少个长度为s的递增子序列。
(3)如果允许在取出的序列中多次使用x1和xn,则从给定序列中最多可取出多少个长
度为s的递增子序列。
第1 行有1个正整数n,表示给定序列的长度。接
下来的1 行有n个正整数x1.....xn 。
第1 行是最长递增子序列的长度s。第2行是可取出的长度为s 的递增子序列个数。第3行是允许在取出的序列中多次使用x1和xn时可取出的长度为s 的递增子序列个数。
4
3 6 2 5
2
2
3
不得不吐槽codevs上面网络流24题好多数据都是很蛋疼的要输出方案又不给spj……鬼知道你数据是用哪种方案啊
啊这题还算正常
第一问LIS随便求
第二问拆点完S向所有x1连流量1费用0的边,所有x2向T连流量1费用0的边,所有x1向x2连流量1费用1的边。因为要表示有没有取这个点
对于所有a[i]<a[j]且i<j的,i2向j1连流量1费用0的边
然后跑最大费用。每次增广搞完如果答案是第一问的最长长度,那么ans++。
第三问就是第二问的建图与1和n有关的边的流量全改inf就对了
#include<cstdio>
#include<iostream>
#include<cstring>
#define LL long long
#define inf 0x3ffffff
#define S 0
#define T 1001
using namespace std;
inline LL read()
{
LL x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int n,ans,flow,cnt,tot;
int a[510];
int mn[510];
struct edge{int from,to,next,v,c;}e[500010];
int head[1010],dis[1010],q[1010],from[1010];
bool mrk[1010];
inline void ins(int u,int v,int w,int c)
{
e[++cnt].to=v;
e[cnt].v=w;
e[cnt].c=c;
e[cnt].from=u;
e[cnt].next=head[u];
head[u]=cnt;
}
inline void insert(int u,int v,int w,int c)
{
ins(u,v,w,c);
ins(v,u,0,-c);
}
inline int bsearch(int x)
{
int l=1,r=ans,s=0;
while(l<=r)
{
int mid=(l+r)>>1l;
if (mn[mid]<=x){s=mid;l=mid+1;}
else r=mid-1;
}
return s;
}
inline bool spfa()
{
for (int i=1;i<=T;i++)dis[i]=inf;
memset(mrk,0,sizeof(mrk));
int t=0,w=1;
dis[S]=0;q[0]=S;mrk[S]=1;
while (t!=w)
{
int now=q[t++];if (t==1005)t=0;
for (int i=head[now];i;i=e[i].next)
if (e[i].v&&dis[now]+e[i].c<dis[e[i].to])
{
dis[e[i].to]=dis[now]+e[i].c;
from[e[i].to]=i;
if (!mrk[e[i].to])
{
mrk[e[i].to]=1;
q[w++]=e[i].to;
if (w==1005)w=0;
}
}
mrk[now]=0;
}
if (dis[T]==inf)return 0;
return 1;
}
inline void mcf()
{
int x=inf;flow=0;
for (int i=from[T];i;i=from[e[i].from])
x=min(x,e[i].v);
for (int i=from[T];i;i=from[e[i].from])
{
e[i].v-=x;
e[i^1].v+=x;
flow+=x*e[i].c;
}
if (flow==-ans)tot++;
}
int main()
{
n=read();
for (int i=1;i<=n;i++)a[i]=read();
ans=1;mn[1]=a[1];
for (int i=2;i<=n;i++)
{
int fnd=bsearch(a[i]);
if (fnd==ans)mn[++ans]=a[i];
else mn[fnd+1]=a[i];
}
printf("%d\n",ans);
cnt=1;
for(int i=1;i<=n;i++)
{
insert(S,i,1,0);
insert(i+n,T,1,0);
insert(i,i+n,1,-1);
}
for (int i=1;i<=n;i++)
for (int j=i+1;j<=n;j++)
if (a[i]<=a[j])insert(i+n,j,1,0);
while (spfa())mcf();
printf("%d\n",tot);
memset(head,0,sizeof(head));
cnt=1;tot=0;
insert(S,1,inf,0);insert(S,n,inf,0);
insert(1+n,T,inf,0);insert(2*n,T,inf,0);
insert(1,1+n,inf,-1);insert(n,2*n,inf,-1);
for(int i=1;i<=n;i++)
{
insert(S,i,1,0);
insert(i+n,T,1,0);
insert(i,i+n,1,-1);
}
for (int i=1;i<n;i++)
for (int j=i+1;j<=n;j++)
if (a[i]<=a[j])
if (i!=1&&j!=n)insert(i+n,j,1,0);
else insert(i+n,j,inf,0);
while (spfa())mcf();
printf("%d\n",tot);
}
codevs1906 最长递增子序列问题的更多相关文章
- (转载)最长递增子序列 O(NlogN)算法
原博文:传送门 最长递增子序列(Longest Increasing Subsequence) 下面我们简记为 LIS. 定义d[k]:长度为k的上升子序列的最末元素,若有多个长度为k的上升子序列,则 ...
- 最长公共子序列(LCS)和最长递增子序列(LIS)的求解
一.最长公共子序列 经典的动态规划问题,大概的陈述如下: 给定两个序列a1,a2,a3,a4,a5,a6......和b1,b2,b3,b4,b5,b6.......,要求这样的序列使得c同时是这两个 ...
- 最长递增子序列 O(NlogN)算法
转自:点击打开链接 最长递增子序列,Longest Increasing Subsequence 下面我们简记为 LIS. 排序+LCS算法 以及 DP算法就忽略了,这两个太容易理解了. 假设存在一个 ...
- 51nod 1134 最长递增子序列
题目链接:51nod 1134 最长递增子序列 #include<cstdio> #include<cstring> #include<algorithm> usi ...
- 动态规划 - 最长递增子序列(LIS)
最长递增子序列是动态规划中经典的问题,详细如下: 在一个已知的序列{a1,a2,...,an}中,取出若干数组组成新的序列{ai1,ai2,...,aim},其中下标i1,i2,...,im保持递增, ...
- 最长递增子序列问题 nyoj 17单调递增最长子序列 nyoj 79拦截导弹
一, 最长递增子序列问题的描述 设L=<a1,a2,…,an>是n个不同的实数的序列,L的递增子序列是这样一个子序列Lin=<aK1,ak2,…,akm>,其中k1< ...
- 2.16 最长递增子序列 LIS
[本文链接] http://www.cnblogs.com/hellogiser/p/dp-of-LIS.html [分析] 思路一:设序列为A,对序列进行排序后得到B,那么A的最长递增子序列LIS就 ...
- 【动态规划】拦截导弹_dilworth定理_最长递增子序列
问题 K: [动态规划]拦截导弹 时间限制: 1 Sec 内存限制: 256 MB提交: 39 解决: 10[提交][状态][讨论版] 题目描述 张琪曼:“老师,修罗场是什么?” 墨老师:“修罗是 ...
- COGS731 [网络流24题] 最长递增子序列(最大流)
给定正整数序列x1,..., xn (n<=500).(1)计算其最长递增子序列的长度s.(2)计算从给定的序列中最多可取出多少个长度为s的递增子序列.(3)如果允许在取出的序列中多次使用x1和 ...
随机推荐
- java byte数组与int,long,short,byte转换
public class DataTypeChangeHelper { /** * 将一个单字节的byte转换成32位的int * * @param b * byte * @return conver ...
- HDU -2524 矩形A + B
找规律题,这种题目比较巧妙,要仔细观察找出规律 1. 假设只有一行,一共有n列,那么由一个小矩形构成的矩形个数为n, 由两个小矩形构成的矩形个数为 n - 1个 .... 由 n 个小矩形构成的矩形个 ...
- ThinkPhp3.2 无法加载模块:Index
http://localhost:444/admin/index.php/Index/index出错:无法加载模块:Index http://localhost:444/admin/index.php ...
- ASP.NET 页面间数据传递的方法
在做WEB开发时,很多地方会涉及到页面间的数据传递.这几天在完善教务基础系统,遇到了这个问题,上网查了一些资料,现总结如下: 说到页面间数据传递,很多人都会想到通过像Session这样的全局变量,但是 ...
- (Spring加载xml时)org.xml.sax.SAXParseException: cvc-elt.1: Cannot find the declaration of element 'beans'.
ApplicationContext ctx = new ClassPathXmlApplicationContext("test.xml");报错 在启动Spring时,报以下错 ...
- IPTV中的EPG前端优化
先看一下IPTV相关情况: l 目前TPTV市场情况 a) 截止今年2月,全国IPTV总用户数达3630.2万,我国移动互联网用户规模接近9亿,人均月接入量近300M,8M宽带达半数,光纤近4成. 图 ...
- Java直接插入算法
直接插入算法是将N个带排序的元素看做成一个有序表和一个无序表. 每次从无序表中取一个元素和有序表比较,重复N-1次完成排序. 直接上代码: package test; public class Tes ...
- 批处理备份和恢复mysql数据库
备份 set "Ymd=%date:~,4%%date:~5,2%%date:~8,2%%time:~0,2%%time:~3,2%%time:~6,2%" md "D: ...
- 【转】Debug和Release区别
VC下Debug和Release区别 最近写代码过程中,发现 Debug 下运行正常,Release 下就会出现问题,百思不得其解,而Release 下又无法进行调试,于是只能采用printf方式逐步 ...
- linux 防火墙--firewalld学习
firewalld是centos7默认的防火墙,相比于iptables重要的优势: 1 支持动态更新: 2 不用重启服务: 同时增加了防火墙的“zone”概念,具体差异没做过多了解,这篇文章只记录fi ...