【iai 5月】升序排列(二)

题目

其实主要在思维

答案就是:不是在最长公差为1子序列 的个数

什么意思呢?

“公差为1序列:就是1 2 3  ,   5 6 7 8 9,  4 5 6这种连续自然数(必须上升)

eg.

7

3 5 4 6 1 7 2

最长公差为1子序列:5 6 7

所以答案为:7 - 3 = 4

我们设这个序列为a_1,a_2,a_3,\cdots,a_n

在最长公差为1子序列b_1,b_2,b_3,\cdots,b_m

不在此序列的是c_1,c_2,c_3,....,c_x移动为d_1,d_2,d_3,....,d_y,

操作方法:

如果把不在子序列内的数分为两个集合,

S_1=\{ k|k\in c,k<b_1\} 和S_2=\{k|k\in c,k>b_x\}

S_1我们按倒序分别放到序列开头,按正序放到序列末尾,就必定是升序

eg.      3        5         4                1        8         7         2  (S_1=\{1,2,3,4\},S_2=\{8\})

           4        3         5                1        8         7         2(4)

           3        4         5                1        8         7         2(3)

           2        3        4         5                1         8         7(2)

          1         2        3         4         5         6         8         7(1)

          1         2        3         4         5         6         7         8(8)

现在要求证:c=d

所以非d的元素必须聚拢在一起,一定是最长公差为1序列,所以剩下来的就是b

所以,移动的就是c,即c=d

上代码:

注意:

用dp[i]表示前i个数的最长公差为1子序列长度

loc[x]=x所在a的位置

          每次考loc计算dp

#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 7, M = 1e3 + 7;
#define int long long
int n, a[N], loc[N], dp[N];
signed main() {
	cin >> n;
	for (int i = 1; i <= n; ++i)
		cin >> a[i], loc[a[i]] = i;
	for (int i = 1; i <= n; ++i) {
		int p = loc[a[i] - 1];
		if (i < p) dp[i] = 1;
		else dp[i] = dp[p] + 1;
	}
	cout << n - (*max_element(dp + 1, dp + n + 1));
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值