51Nod 1241 特殊的排序 —— 思维DP

Posted dolfamingo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了51Nod 1241 特殊的排序 —— 思维DP相关的知识,希望对你有一定的参考价值。

题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1241

 

题目来源: 摩根斯坦利的比赛题
基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题
技术分享图片 收藏
技术分享图片 关注
一个数组的元素为1至N的整数,现在要对这个数组进行排序,在排序时只能将元素放在数组的头部或尾部,问至少需要移动多少个数字,才能完成整个排序过程?
 
例如:
2 5 3 4 1 将1移到头部 => 
1 2 5 3 4 将5移到尾部 =>
1 2 3 4 5 这样就排好了,移动了2个元素。
 
给出一个1-N的排列,输出完成排序所需的最少移动次数。
Input
第1行:1个数N(2 <= N <= 50000)。
第2 - N + 1行:每行1个数,对应排列中的元素。
Output
输出1个数,对应所需的最少移动次数。
Input示例
5
2
5
3
4
1
Output示例
2

 

代码如下:

技术分享图片
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <vector>
 6 #include <cmath>
 7 #include <queue>
 8 #include <stack>
 9 #include <map>
10 #include <string>
11 #include <set>
12 using namespace std;
13 typedef long long LL;
14 const int INF = 2e9;
15 const LL LNF = 9e18;
16 const int MOD = 1e9+7;
17 const int MAXM = 1e5+10;
18 const int MAXN = 5e4+10;
19 
20 int a[MAXN],vis[MAXN], dp[MAXN];
21 int main()
22 {
23     int n;
24     while(scanf("%d",&n)!=EOF)
25     {
26         for(int i = 1; i<=n; i++)
27             scanf("%d",&a[i]);
28 
29         int cnt = 0;
30         memset(vis, 0, sizeof(vis));
31         for(int i = 1; i<=n; i++)
32         {
33             dp[a[i]] = 1;
34             if(vis[a[i]-1]) dp[a[i]] += dp[a[i]-1];
35             vis[a[i]] = 1;
36             cnt = max(cnt, dp[a[i]]);
37         }
38         printf("%d\n", n-cnt);
39     }
40 }
View Code

 

以上是关于51Nod 1241 特殊的排序 —— 思维DP的主要内容,如果未能解决你的问题,请参考以下文章

51nod 1241 特殊的排序

51nod 1241 特殊的排序

51nod 1241 特殊的排序(动态规划)

51nod 1376 最长递增子序列的数量(不是dp哦,线段树 +  思维)

51nod1201_dp思维题

51nod1241(连续上升子序列)