题意:n 张带标号的牌和 n 张空白牌,n 张在手上剩下在牌堆里(牌堆有序),每次可以从手上选一张牌放牌堆底部并从牌堆顶部抽一张牌,需要使牌堆从上到下递增地放 1 ~ n,求最小操作数。1≤n≤2×10^5。
题解:
首先尝试不打空白牌能否直接完成。如果能就是最优解,否则最优解一定是先打若干空白牌然后再也不打空白牌。计 pi 为 i 在牌堆的初始位置(初始在手上为 0),那么答案为 maxi=1n(pi−i+1+n)(每张牌最早在第 pi+1 张被打出,还要打 n−i 张)。
参考博客:https://ouuan.github.io/Codeforces-Round-564-%E4%B8%AD%E6%96%87%E9%A2%98%E8%A7%A3/
#include<bits/stdc++.h>
using namespace std ;
#define N 200005
typedef long long ll ;
int a[N] , b[N] ;
int n ;
int main()
{
int i , j ;
int max1 ;
bool flag = 0 ;
scanf("%d" , &n) ;
for(i = 1 ; i <= n ; i ++)
scanf("%d" , &a[i]) ;
for(i = 1 ; i <= n ; i ++)
scanf("%d" , &b[i]) ;
j = n ;
while(j >= 2 && b[j] == b[j - 1] + 1 && b[j - 1])
j -- ;
if(b[j] == 1)
{
for(i = 1 ; i < j ; i ++)
if(b[i] && b[i] - b[n] < i + 1)
{
flag = 1 ;
break ;
}
if(!flag)
{
printf("%d" , n - b[n]) ;
return 0 ;
}
}
max1 = n ;
for(i = 1 ; i <= n ; i ++)
if(b[i])
max1 = max(max1 , i + 1 + n - b[i]) ;
printf("%d" , max1) ;
}