51 Nod 1700 首尾排序法
2024-09-05 03:57:33
1700 首尾排序法
有一个长度为n的数组 p1, p2, p3, ⋯, pnp1, p2, p3, ⋯, pn ,里面只包含1到n的整数,且每个数字都不一样。现在要对这个数组进行从小到大排序,排序的时候只能是把一个数字拿过来放到数组末尾或者开头,问最少要操作几次才能使得这个数组从小到大排序。
样例解释:
先把4移动到最后,然后再把5移动到后。
收起
输入
单组测试数据。
第一行一个整数n (1≤n≤100000),表示数组的长度。
第二行有n个整数 pi (1≤pi≤n, 如果 i≠j,那么pi≠pj ) ,表示数组中的数字。
输出
输出一个整数,表示最少要操作几次才能使得数组从小到大有序。
输入样例
5
4 1 2 5 3
输出样例
2
思路:求一个最长的连续的子串(如样例中的1,2,3) 的长度len, 答案即为 n-len
代码如下:
#include<bits/stdc++.h>
using namespace std;
int a[100005];int n;
int par[100005];
bool vis[100005];
int dp[100005];
int len=0;
int dfs(int i)
{
if(par[i]==i){dp[i]=1;return 1;}
int p=par[i];
if(dp[p]!=0){dp[i]=dp[p]+1;return dp[i];}
return dfs(par[i]);
}
int main()
{
//freopen("in.txt","r",stdin);
scanf("%d",&n);
for(int i=0;i<n;i++)scanf("%d",&a[i]);
for(int i=1;i<=n;i++)par[i]=i;
for(int i=0;i<n;i++)
{
if(vis[a[i]-1])
{
vis[a[i]-1]=0;par[a[i]]=a[i]-1;
vis[a[i]]=1;
}
else vis[a[i]]=1;
}
for(int i=1;i<=n;i++)
len=max(dfs(i),len);
int ans=n-len;
cout<<ans<<endl;
return 0;
}
最新文章
- 对于挑战书上的很久之前都看不懂的DP看懂的突破
- Get请求中文乱码的几种解决方式
- Node入门(转)
- 一致性哈希(consistent hashing)算法
- Python中如何写控制台进度条的整理
- uploadify插件的使用
- php面向对象设计模式
- UILabel,UITextField,UIButton三大基础控件总结
- 详解js和jquery里的this关键字
- C#打印九九乘法表
- 怎样获取HTML5视频的持续时间
- 开发一个简单的chrome插件-解析本地markdown文件
- 浅谈openstack中使用linux_bridge实现vxlan网络
- Vue2.0 探索之路——生命周期和钩子函数的一些理解
- VB.NET 编程元素支持更改总结
- BCH/BSV coin split troubleshooting
- BZOJ 3529 数表(莫比乌斯+树状数组)
- cxGrid显示行号
- linux下添加用户到sudo组
- .net使用QQ邮箱发送邮件