HDU5500 Reorder the Books(脑洞?)

Reorder the Books

Problem Description
dxy has a collection of a series of books called “The Stories of SDOI”,There are n(n≤19) books in this series.Every book has a number from 1 to n.

dxy puts these books in a book stack with the order of their numbers
increasing from top to bottom. dxy takes great care of these books and
no one is allowed to touch them.

One day Evensgn visited dxy’s home, because dxy was dating with his
girlfriend, dxy let Evensgn stay at home himself. Evensgn was curious
about this series of books.So he took a look at them. He found out
there was a story about “Little E&Little Q”. While losing himself in

Knowing that dxy would be back soon,Evensgn needed to get the books
ordered again.But because the books were too heavy.The only thing
Evensgn could do was to take out a book from the book stack and and
put it at the stack top.

Give you the order of the disordered books.Could you calculate the
minimum steps Evensgn would use to reorder the books? If you could
solve the problem for him,he will give you a signed book “The Stories
of SDOI 9: The Story of Little E” as a gift.

Input
There are several testcases.

There is an positive integer T(T≤30) in the first line standing for
the number of testcases.

For each testcase, there is an positive integer n in the first line
standing for the number of books in this series.

Followed n positive integers separated by space standing for the order
of the disordered books,the ith integer stands for the ith book’s
number(from top to bottom).

Hint: For the first testcase:Moving in the order of book3,book2,book1
,(4,1,2,3)→(3,4,1,2)→(2,3,4,1)→(1,2,3,4),and this is the best way to
reorder the books. For the second testcase:It’s already ordered so
there is no operation needed.

Output
For each testcase,output one line for an integer standing for the minimum steps Evensgn would use to reorder the books.

Sample Input
2
4
4 1 2 3
5
1 2 3 4 5

Sample Output
3

首先先翻译一下题面,看到这样的题面谁都头大。。。这题是突然开脑洞想出来的。。。
题意是说给你一个打乱顺序的区间,要求变成从小到大排列。每次移动一个数的时候都要把这个数放到区间的最前面,问最少的变成目标区间的操作次数。

例如对于一个给定的区间3 5 7 4 2 1 6,最大的数是7,那么7下面的数一定是要被扔到上面去的,只是扔的顺序可能不同。对于给出的样例6 是次大,但是6需要被扔上去,所以3 5这些在7上面在6下面的数(理解为6已经被扔上去了)都需要被扔上去,所以答案就是7-1=6;
再例如对于另一个区间 6 5 7 4 2 1 3,6在7的上面。只需要把6 ~ 7之间的数扔上去(假想),接着比较6和5,如5还在6的上面 那就需要把5和6之间的数扔上去(假想),直到上面的数没有连续比它小的了。

正确性呢就是对于一个区间,最差的答案是n-1,也就是那个最大的数一定不需要扔上去,其余的数都需要被扔上去。一旦出现大数上面有连续的比它小的数(类似5 6,4 5)这种,那么这个数显然不需要再一次被扔,因为这样一定会让答案更优。

正解:所以可以直接用一个数组记录下每个数的位置,如果发现一个连续比他小的数的位置在他上面,ans–,直到上面没有这样的数。最坏复杂度是O(N*t)

代码如下:

#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
const int maxn=2000005;
int shu[maxn],wz[maxn];
int main()
{
    int t;
    scanf("%d",&t);
    for(int s=1;s<=t;s++)
    {
        int n,dq;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&shu[i]);
            wz[shu[i]]=i;
        }
        int ans=n-1;
        int now=n,nowwz=wz[n];
        while(true)
        {
            now--;
            if(now==0) break;
            if(wz[now]<nowwz)
            {
                nowwz=wz[now];
                ans--;
            }
            else break;
        }
        printf("%d\n",ans);     
    }
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值