zoukankan      html  css  js  c++  java
  • UVA

    给出一个长度不超过500的环状排列,每次操作可以交换任意两个数,求把这个排列变成有序的环状排列所需的最小操作次数。

    首先把环状排列的起点固定使其成为链状排列a,枚举排好序时的状态b(一种有2n种可能),则b可以看成是原状态a的一个置换,把a变为b所需的最小交换次数即为a的长度n减去置换循环节的数量。

     1 #include<bits/stdc++.h>
     2 
     3 using namespace std;
     4 typedef long long ll;
     5 const int N=500+10;
     6 const int inf=0x3f3f3f3f;
     7 int n,a[N],b[N],c[N],vis[N],ans;
     8 
     9 int cir(int* a,int* b,int n) {
    10     int ret=0;
    11     memset(vis,0,sizeof vis);
    12     for(int i=1; i<=n; ++i)c[a[i]]=b[i];
    13     for(int i=1; i<=n; ++i)if(!vis[i]) {
    14             ++ret;
    15             for(int j=i; !vis[j]; j=c[j])vis[j]=1;
    16         }
    17     return ret;
    18 }
    19 
    20 int main() {
    21     while(scanf("%d",&n)&&n) {
    22         ans=inf;
    23         for(int i=1; i<=n; ++i)scanf("%d",&a[i]);
    24         for(int i=1; i<=n; ++i)b[i]=i;
    25         do {
    26             ans=min(ans,n-cir(a,b,n));
    27             for(int i=1; i<n; ++i)swap(b[i],b[i+1]);
    28         } while(b[1]!=1);
    29         for(int i=1; i<=n; ++i)b[i]=n-i+1;
    30         do {
    31             ans=min(ans,n-cir(a,b,n));
    32             for(int i=1; i<n; ++i)swap(b[i],b[i+1]);
    33         } while(b[1]!=n);
    34         printf("%d
    ",ans);
    35     }
    36     return 0;
    37 }
  • 相关阅读:
    递归实现全排列问题
    LeetCode
    LeetCode
    连续子元素最大和
    简单模板view调用
    如何清除PHP中不需要的Layout模板
    Model中设置表单验证方法
    数据修改操作
    MVC模式tp框架四中路由形式
    zend Framework的MVC模式的搭建
  • 原文地址:https://www.cnblogs.com/asdfsag/p/10354061.html
Copyright © 2011-2022 走看看