团体程序设计天梯赛 决赛 L2 列车调度

题目链接:https://www.patest.cn/contests/gplt/L2-014

题意:让我们求出这个序列最少的下降序列个数,而最少的下降序列个数就等于整个序列最长上升子序列的长度。

由于小编的疏忽,觉得这就是个人人皆知的定理,没有给出证明过程,让读者感到了困惑,这里小编由衷的道歉,同时感谢A_LeiQ同学的提醒,这里小编给出一个证明过程。

其实这个证明过程得提一个定理,那就是偏序集的Dilworth定理,关于偏序集,离散数学中的概念,这里限于篇幅,小编不在详细介绍,这里证明一下这个在这个地方的Dilworth定理的运用。

首先,我们设一个数a的值小于等于另一个数b且它的位置在这个数的前面(或同一个位置)表示a≤b,用S表示整个集合,用极小元来表示只有自己能和自己确立≤关系的数,用链表示一个子集,里面的元素互相都能确定≤的关系,用反链来表示一个子集,里面的元素互相都不能确定≤的关系,我们设最少反链划分数是p,最长链长度是r。

1.先证p≥r。这是显然的,因为最长链长度是r,r个元素中的任意两个都可以比较,因此它们必定两两属于不同的反链,因此反链个数≥r,即p≥r。用这个例子来说的话就是,一个上升序列中每一个数肯定不可能出现在同一个下降子序列中。

2.再证r≥p。设X1=S。找出X1的所有极小元组成集合Z1,将其从X1删之,得到X2,再找出X2的所有极小元组成集合Z2(特别注意X2中的任何元素a2,在X1中必然存在一个元素a1使得a1≤a2,否则a2可以放到X1中,这与X1的选取矛盾),再将Z2从X2中删除,得到X3,……这样一直下去,总存在一个k使得XK不空但X(K+1)为空。这样便得到一条链a1,a2,a3,……,ak,其中ai属于Xi。由于r是最长链长度,因此r≥k。另一方面,我们也得到了一个反链划分,即X1,X2,X3,……,XK。由于p是最少反链划分,因此k≥p。因此有r≥p。这里不懂的同学可以就拿样例来模拟一下,很容易就能发现这个证明过程的正确性。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 100000+5;
int a[maxn], dp[maxn];
int main()
{
	int n;
	scanf("%d", &n);
	for(int i=0; i<n; i++) scanf("%d", &a[i]);
	dp[0] = a[0];
	int num = 0;
	for(int i=1; i<n; i++)
		if(dp[num] < a[i])
			dp[++num] = a[i];
		else{
			int pos = upper_bound(dp,dp+num,a[i])-dp;
			dp[pos] = a[i];
		}
	printf("%d\n", num+1);
}


评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值