最小不升子序列覆盖

目录

题目概述:

题目背景:

题目描述:

输入格式:

输出格式:

输入样例:

输出样例:

说明提示:

解析:

方法一:暴力算法

方法二:Dilworth 定理


题目概述:

题目背景:

不升子序列的定义:每个数都小于等于上一个数。

题目描述:

输入一个长度为n的序列Ai……An, 将此序列分为若干个子序列(不要求连续),使得每个子序列为不升子序列。求最少要分成多少个子序列。

输入格式:

第一行,一个整数n

第二行,n个整数,分别为Ai

输出格式:

一个正整数,为最少要分成的子序列个数。

输入样例:

6

2 1 2 7 2 3

输出样例:

3

说明提示:

样例1说明:将{2,1},{2,2},{7,3}分为一组

数据范围:

数据点

N

Ai

分值(个)

1-2

20

100000

7

3-4

100

8

5-7

1000000

10

8-9

1000000000

13

10

1000000000

1000000

14

注:此题为洛谷私人题库,到

U376600 最小将序列覆盖 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

提交答案


解析:

方法一:暴力算法

这道题我们要用 “贪心算法”。

首先,我们来分析这道题,我们要让子序列最小,一定要让尽可能地接上上一个字符串,我们的贪心策略便出来了:

于是,我们开一个二维数组,然后我们去操作:

首先,第一个数字二,我们放在一个新数组,并将后面接上2:

接着,看1,因为1<2,所以我们接在后面,并重置后面

再看2,因为2>1,所以我们开一个新的并接好后面的

然后,我们继续操作,这里不做详细说明……

最终,表格成为这样:

最后,二维数组的行数变为答案。

接着,程序实现:

但是,很多人都看出来了,这样百分百超时,因为,这是n^2算法!

不过,找到最小的可接子序列可以用二分查找!

但最大的问题可能你们未能发现:空间复杂度!

看来,我们这样的话只能得30分了


方法二:Dilworth 定理

很显然,我们这里可以引用一个著名定理:Dilworth 定理:最⻓链=最⼩反链覆盖

我们可以把最小不升子序列覆盖改为最长上升子序列。

于是,我们编写一个复杂度为n的程序:

简简单单十几行搞定!

如果需要Dilworth定理的证明,请到云剪贴板 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)查看。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值