zoukankan      html  css  js  c++  java
  • 序列

    【问题描述】
    给定一个 1~n 的排列 x,每次你可以将 x1~xi 翻转。你需要求出将序列变为
    升序的最小操作次数。有多组数据。
    【输入格式】
    第一行一个整数 t 表示数据组数。
    每组数据第一行一个整数 n,第二行 n 个整数 x1~xn。
    【输出格式】
    每组数据输出一行一个整数表示答案。
    【样例输入输出】
    sequence.in
    1
    8
    8 6 1 3 2 4 5 7
    sequence.out
    7
    【数据范围】
    对于 100%的测试数据,t=5,n<=25。
    对于测试点 1,2,n=5。
    对于测试点 3,4,n=6。
    对于测试点 5,6,n=7。
    对于测试点 7,8,9,n=8。
    对于测试点 10,n=9。
    对于测试点 11,n=10。
    对于测试点 i (12<=i<=25),n=i。

    每次将 n 翻转到 x1 再翻转到 xn,可以得到一个不超过
    2n-2 步的做法。由于步数不多,我们可以使用迭代加深搜索。


    我们发现每次翻转只会改变一对相邻数对,因此对于一个状态求出相差>1 的相邻数对的数量,剩余步数一定大于这个值。加上这个剪枝就能通过本题。
    时间复杂度 O(能过)

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<map>
     6 using namespace std;
     7 int a[26],ans,n,zyys,T;
     8 int find()
     9 {int i;
    10   for (i=n;i>=1;i--,zyys++)
    11     if (a[i]!=i) return i;
    12 }
    13 int count()
    14 {int i;
    15   int cnt=0;
    16   for (i=n-1;i>=1;i--,zyys++)
    17     if (abs(a[i]-a[i+1])!=1) cnt++;
    18   return cnt;
    19 }
    20 bool dfs(int x)
    21 {int i,j,flag;
    22   int aa[26]={0};
    23   //if (zyys>90000000) return 1;
    24   if (x>ans) return 0;
    25   if (x+count()>ans) return 0;
    26   flag=1;
    27   for (i=n;i>=1;i--,zyys++)
    28     if (a[i]!=i) 
    29       {flag=0;break;}
    30   int r=i;
    31   if (flag)
    32     {
    33       ans=x;
    34       return 1;
    35     }
    36   memcpy(aa,a,sizeof(aa));
    37   zyys+=n;
    38   for (i=1;i<=r;i++)
    39     {zyys++;
    40       for (j=1;j<=i;j++,zyys++)
    41     a[j]=aa[i-j+1];
    42       if (dfs(x+1)) return 1;
    43       for (j=1;j<=i;j++,zyys++)
    44     a[j]=aa[j];
    45     }
    46   return 0;
    47 }
    48 int main()
    49 {int i,pos;
    50   cin>>T;
    51   while (T--)
    52     {
    53       cin>>n;
    54       ans=n*2-2;
    55       zyys=0;
    56       for (i=1;i<=n;i++)
    57     {zyys++;
    58       scanf("%d",&a[i]);
    59       if (a[i]==n) pos=i;
    60     }
    61       for (i=1;i<=2*n-2;i++)
    62     {ans=i;
    63       if (dfs(0)) break;
    64     }
    65       cout<<ans<<endl;
    66     }
    67 }
  • 相关阅读:
    9.内存的了解
    8.时钟初始化
    3.2Linux的模块驱动
    3.1Linux内核的配置和编译
    5.10TCP客户端服务器
    5.9UDP客户端服务器-基于OK6410
    5.8fork父子进程
    4.NFC前台调度系统
    3.非标准的NDEF格式数据解析--IsoDep
    Android 布局学习之——LinearLayout属性baselineAligned的作用及baseline
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/7793044.html
Copyright © 2011-2022 走看看