• 篝火晚会


    题目描述

    佳佳刚进高中,在军训的时候,由于佳佳吃苦耐劳,很快得到了教官的赏识,成为了“小教官”。在军训结束的那天晚上,佳佳被命令组织同学们进行篝火晚 会。一共有n个同学,编号从1到n。一开始,同学们按照1,2,……,n的顺序坐成一圈,而实际上每个人都有两个最希望相邻的同学。如何下命令调整同学的 次序,形成新的一个圈,使之符合同学们的意愿,成为摆在佳佳面前的一大难题。

    佳佳可向同学们下达命令,每一个命令的形式如下:

    (b1, b2,... bm -1, bm)

    这里m的值是由佳佳决定的,每次命令m的值都可以不同。这个命令的作用是移动编号是b1,b2,…… bm的这m个同学的位置。要求b1换到b2的位置上,b2换到b3的位置上,……,要求bm换到b1的位置上。执行每个命令都需要一些代价。我们假定如果 一个命令要移动m个人的位置,那么这个命令的代价就是m。我们需要佳佳用最少的总代价实现同学们的意愿,你能帮助佳佳吗?

    输入输出格式

    输入格式:

    输入文件fire.in的第一行是一个整数n(3 <= n <= 50000),表示一共有n个同学。其后n行每行包括两个不同的正整数,以一个空格隔开,分别表示编号是1的同学最希望相邻的两个同学的编号,编号是2的 同学最希望相邻的两个同学的编号,……,编号是n的同学最希望相邻的两个同学的编号。

    输出格式:

    输出文件fire.out包括一行,这一行只包含一个整数,为最小的总代价。如果无论怎么调整都不能符合每个同学的愿望,则输出-1。

    输入输出样例

    输入样例#1: 复制
    4
    
    3 4
    
    4 3
    
    1 2
    
    1 2
    
    输出样例#1: 复制
    2

    说明

    对于30%的数据,n <= 1000;

    对于全部的数据,n <= 50000。

    仔细观察发现,所有可能的情况都是由其中一种情况进行环移或翻转得到的,

    比如样例有一种情况为:1 4 2 3

    其余情况为:

    3 1 4 2

    2 3 1 4

    4 2 3 1

    3 2 4 1

    1 3 2 4

    4 1 3 2

    2 4 1 3

    (观察一下)

    代价也就是与开始不相等的数的个数

    比如要排成1 4 2 3

    原序列1 2 3 4

    只有1不用移,4 2 3都不在目标序列上,因此代价为3

    因为 比如遇到一个不应该放在原来的位置上,

    则把它放到目标位置上,

    但又把另一个元素挤了出来,

    将挤出来的元素放到目标位置上,

    又会有元素被挤出来,

    继续进行相同的操作.……

    直到所有元素(人)都安排好(心满意足)了。

    再计算代价,就是上述结论。

    但是,环移操作很费时,n^2,怎么办?

    当然不能直接移,可以记f[i]为有f[i]个元素要进行i次环移操作才能移到自己的位置上

    求f[i]的最大值就行了

    再翻转做一次就行了

    判断也很好判断

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 int cnt,a[50001],n,l[50001],r[50001],ans1[50001],ans2[50001],ans;
     7 int main()
     8 {int i,j;
     9   cin>>n;
    10   for (i=1;i<=n;i++)
    11     scanf("%d%d",&l[i],&r[i]);
    12   a[1]=1;
    13   for (i=1;i<=n;i++)
    14     if (r[l[i]]!=i&&l[l[i]]!=i||l[r[i]]!=i&&r[r[i]]!=i)
    15       {
    16     cout<<-1;
    17     return 0;
    18       }
    19   a[2]=l[1];
    20   for (i=2;i<n;i++)
    21     {
    22       if (r[a[i]]==a[i-1]) a[i+1]=l[a[i]];
    23       else a[i+1]=r[a[i]];
    24     }
    25   for (i=1;i<=n;i++)
    26     {
    27       ans1[(a[i]-i+n)%n]++;
    28       ans2[(a[i]+i-1)%n]++;
    29     }
    30   for (i=0;i<n;i++)
    31     ans=max(ans,max(ans1[i],ans2[i]));
    32   cout<<n-ans;
    33 }
  • 相关阅读:
    附加数据库 对于 服务器“00-PC”失败
    SQL 语句转换格式函数Cast、Convert
    sql语句:union
    ISNULL-sqlserver语句
    SQL中的CASE WHEN语句
    SQL SELECT INTO 语句
    Sql语句中IN等方面的用法
    combobox的不常用的方法和将txt文本内容加到textbox中显示
    程序员:“菜鸟”和“大神”差距在哪
    过劳死离我们有多远?
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/7795614.html
Copyright © 2020-2023  润新知