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;
}

最新文章

  1. 对于挑战书上的很久之前都看不懂的DP看懂的突破
  2. Get请求中文乱码的几种解决方式
  3. Node入门(转)
  4. 一致性哈希(consistent hashing)算法
  5. Python中如何写控制台进度条的整理
  6. uploadify插件的使用
  7. php面向对象设计模式
  8. UILabel,UITextField,UIButton三大基础控件总结
  9. 详解js和jquery里的this关键字
  10. C#打印九九乘法表
  11. 怎样获取HTML5视频的持续时间
  12. 开发一个简单的chrome插件-解析本地markdown文件
  13. 浅谈openstack中使用linux_bridge实现vxlan网络
  14. Vue2.0 探索之路——生命周期和钩子函数的一些理解
  15. VB.NET 编程元素支持更改总结
  16. BCH/BSV coin split troubleshooting
  17. BZOJ 3529 数表(莫比乌斯+树状数组)
  18. cxGrid显示行号
  19. linux下添加用户到sudo组
  20. .net使用QQ邮箱发送邮件

热门文章

  1. 十一、三星平台framebuffer驱动
  2. 深度剖析Kubernetes API Server三部曲 - part 2
  3. C# 对象互转
  4. css border 三角形阴影(不规则图形阴影) &amp; 多重边框的制作
  5. (一)Struts2 基础
  6. c# 实体类转XML
  7. C# 钉钉第三方开发接入
  8. Win10安装PyQt5与Qt Designer
  9. clipboard兼容各个浏览器,不需要设置权限
  10. 【vue开发】vue插件的install方法