http://acm.csu.edu.cn:20080/csuoj/problemset/problem?pid=2191
Description
Wells有一堆N个积木,标号1~N,每个标号只出现一次 由于Wells是手残党,所以每次只能取出一块积木放在积木顶层 现在Wells想知道至少需要操作几次可以把积木堆成从顶至底标号升序 不论什么都很菜的Wells显然不知道怎么做 所以作为人生赢家的你义不容辞的决定帮助可怜的Wells
Input
第一行一个正整数N
接下来N行,从顶至底描述每块积木的标号
Output
输出一行,为最小操作次数
Sample Input
3
3
2
1
Sample Output
2
Hint
样例数据的两次操作(3,2,1)->(2,3,1)->(1,2,3) N<=10^5
Source
思路:思维题目,因为每次可以任选一块放到顶部,因此每次必定要做最优的选择,那么其实我们只关心j与j+1的位置关系(1<=j<=n-1)。(1)当pos[j]<pos[j+1]时,j和j+1都不需要移动,因为按照要求后续操作必定可以把j与j+1之间的积木都拿掉,因此可以少做一步移动操作;(2)当pos[j]>pos[j+1]时,此时必定要把j移到顶部,由此造成后续积木必定都要按顺序移到顶部。
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
int n;
int a[100005];
int pos[100005];
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
pos[a[i]]=i;
}
int ans=1;
for(int i=n-1;i>=1;i--)
{
if(pos[i]<pos[i+1])
++ans;
else
break;
}
printf("%d\n",n-ans);
return 0;
}