【DP】Gym101623A Ascending Photo

【题目】
原题地址
给定一个序列,问最少将序列切多少刀并重排后,序列单调不降。 n ≤ 1 0 6 n\leq 10^6 n106

【解题思路】
这个 DP \text{DP} DP十分有趣啊。
首先我们先把所有数离散化后都用挡板分开,现在问题就是去掉最多的挡板。观察到当存在连续序列 ( a , a + 1 , a + 2 ) (a,a+1,a+2) (a,a+1,a+2) a + 1 a+1 a+1在数组中不唯一时,去掉 ( a , a + 1 ) (a,a+1) (a,a+1)的挡板可能导致 ( a + 1 , a + 2 ) (a+1,a+2) (a+1,a+2)的挡板无法去除。

我们用 f i f_i fi表示去除数值 ( 0 , 1 ) (0,1) (0,1) ( i , i + 1 ) (i,i+1) (i,i+1)的所有可去除挡板数量。注意到 f f f的值和去除那一块可选挡板有关因此我们需要加一维,设 f i , j f_{i,j} fi,j表示去除 ( i , i + 1 ) (i,i+1) (i,i+1)挡板时考虑位置 ( j , j + 1 ) (j,j+1) (j,j+1)

即首先 i i i j j j有条件 a j = i , a j + 1 = i + 1 a_j=i,a_{j+1}=i+1 aj=i,aj+1=i+1
f i , j = max ⁡ ( f i − 1 , j ′ + [ j 不 是 j ′ 产 生 的 冲 突 位 置 ] ) f_{i,j}=\max(f_{i-1,j'}+[j不是j'产生的冲突位置]) fi,j=max(fi1,j+[jj])
这个条件等价于 j = j ′ + 1 j=j'+1 j=j+1 a j a_j aj不唯一。

那么对于一个 j ′ j' j,最多产生一个冲突位置 j ′ + 1 j'+1 j+1(当a_{j’+1}唯一就不是冲突位置)。
对于一个 j j j,只可能是一个位置 j ′ = j − 1 j'=j-1 j=j1的冲突位置。

如果我们把 f i f_i fi看作一张表,最后求的就是 f n f_n fn的最大值。

观察转移方程,从f_i向f_{i+1}转移的时候,求 max ⁡ \max max的是 f i f_i fi这张表的所有元素,但其中有些元素加了 1 1 1 j j j不是 j ′ j' j的冲突位置)。

所以,我们只需保存这张表最大的那些值就行了。具体来说我们只用保留最大值和次大值:
回顾条件,当我们保存了两个 f f f值最大的 j ′ j' j对应的冲突位置时,那么求 f i , j f_{i,j} fi,j就能一定找到一个不冲突的位置,然后累计加上 1 1 1

所以最终复杂度为 O ( n ) O(n) O(n)

【参考代码】

#include<bits/stdc++.h>
#define pb push_back
#define mkp make_pair
#define fi first
#define se second
using namespace std;

typedef long long ll;
typedef pair<int,int> pii;
const int N=1e6+10;
int n,sz,b[N];
vector<int>a,pos[N];

int read()
{
	int ret=0,f=1;char c=getchar();
	while(!isdigit(c)) {if(c=='-')f=0;c=getchar();}
	while(isdigit(c)) ret=ret*10+(c^48),c=getchar();
	return f?ret:-ret;
}

int main()
{
#ifndef ONLINE_JUDGE
	freopen("A.in","r",stdin);
	freopen("A.out","w",stdout);
#endif
	n=read();
	for(int i=1;i<=n;++i)
	{
		int x=read();
		if(a.empty() || a.back()!=x) a.pb(x);
	}
	n=(int)a.size();
	for(int i=0;i<n;++i) b[i]=a[i];
	sort(b,b+n);sz=unique(b,b+n)-b;
	for(int i=0;i<n;++i) a[i]=lower_bound(b,b+sz,a[i])-b,pos[a[i]].pb(i);
	pii s1=mkp(0,n),s2=mkp(0,n);
	for(int i=0;i<sz-1;++i)
	{
		pii t1=s1,t2=s2;
		for(int j=0;j<(int)pos[i].size();++j)
		{
			int p=pos[i][j];
			if(p==n-1 || a[p]+1!=a[p+1]) continue;
			pii s=mkp(0,n);
			if(p^s1.se) s=s1; else s=s2;
			++s.fi;s.se=p+1;
			if(pos[i+1].size()==1) s.se=n;
			if(s>t1) t2=t1,t1=s;
			else if(s>t2) t2=s;
		}
		s1=t1;s2=t2;
	}
	printf("%d",n-s1.fi-1);

	return 0;
}

【总结】
层层递进的思想,挺难想的吧qwq。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
自2020年以来,自动驾驶汽车(Autonomous Vehicle)在这一领域取得了显著进展。 自动驾驶汽车通过使用先进的传感技术,如雷达、激光雷达和摄像头,以及深度学习和人工智能算法,实现了车辆的自主驾驶。它们能够感知周围环境,了解道路状况,并做出相应的决策和行驶动作,从而实现无需人类操控的车辆行驶。 自动驾驶汽车在2020年迅速崭露头角。它们的技术日益成熟,不断的实验和测试表明其在安全性和性能方面已经取得了显著的突破。虽然仍然存在一些挑战,比如在复杂城市环境中导航和处理紧急情况,但这些问题正经过不断的研究和改进来得以解决。 在未来,自动驾驶汽车有望在各个领域发挥重要作用。首先,它们将可以提高道路交通的安全性。由于自动驾驶车辆不受人类司机的疲劳、分心和驾驶误差的限制,它们的驾驶能力更为稳定和准确。其次,自动驾驶汽车还能够提高交通效率。通过与其他车辆实时通信和协同,它们可以避免交通堵塞和减少事故发生,从而减少交通拥堵和行车时间成本。 此外,自动驾驶汽车也将为交通出行带来便利和舒适性。乘客可以更轻松地进行其他活动,如工作、休息或娱乐,而不必担心驾驶问题。老年人和残障人士也将能够自由独立地出行,提高他们的生活质量。 综上所述,作为2020年的重要趋势,自动驾驶汽车具有广阔的应用前景。通过不断的创新和发展,它们将在道路交通安全、交通效率和出行体验方面取得进一步的提升。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值