• POJ 3270 Cow Sorting 置换群


    Cow Sorting

    接触到置换群的概念,对于一个(1~n)的一个排列a1, a2, a3...an

        1   2   3   4   5 ... n

       a1  a2 a3 a4 a5...an

    看作是一个置换,那么将其写为若干个不相交的循环的乘积形式(A1, A2, ... Ap1)(B1, B2, ... Bp2)... ...,例如

       1 2 3 4 5 6

       3 5 6 4 2 1

    可以写为(1 3 6)(2 5)(4)的形式,这里可以看成有3个循环(可以理解为上面的1 3 6这个集合,对应在下面也是 1 3 6)

    那么对应在每一个循环中,可以通过最多Ki - 1此交换使得这个循环有序,这里的Ki表示第i个循环的集合的大小。也就是说每交换一次可以使得一个元素回到自己的位置,由于交换的代价是这两个元素值的和,那么根据贪心的思想,每次选择用这个循环中的最小值将其他元素交换到对应的位置上去。那么总代价就是

    SUMi + (Ki - 2) * Mi

    这里Mi表示第i个循环的最小值,SUMi表示第i个循环的和,Ki表示这个循环的元素的个数。

    另外,从另一个角度出发,如果整个序列的最小值非常小,那么我们判断是不是可以先用整个序列的最小值把第i个循环的最小值Mi换出来,然后将这个集合(循环)交换到有序后,再将Mi交换回来,这样总代价就是

    SUMi + (Ki + 1) * MIN + Mi

    其中MIN表示整个序列的最小值。

    那么,最后的答案就是  ans = SIGMA{ SUMi + min{(Ki - 2) * Mi,  (Ki + 1) * MIN + Mi} }

     1 #pragma comment(linker, "/STACK:1677721600")
     2 #include <map>
     3 #include <set>
     4 #include <stack>
     5 #include <queue>
     6 #include <cmath>
     7 #include <ctime>
     8 #include <bitset>
     9 #include <vector>
    10 #include <cstdio>
    11 #include <cctype>
    12 #include <cstdarg>
    13 #include <cstring>
    14 #include <cstdlib>
    15 #include <iostream>
    16 #include <algorithm>
    17 using namespace std;
    18 #define INF 0x3f3f3f3f
    19 #define inf (-((LL)1<<40))
    20 #define root 1, 1, n
    21 #define middle ((L + R) >> 1)
    22 #define lson k<<1, L, (L + R)>>1
    23 #define rson k<<1|1,  ((L + R)>>1) + 1, R
    24 #define mem0(a) memset(a,0,sizeof(a))
    25 #define mem1(a) memset(a,-1,sizeof(a))
    26 #define mem(a, b) memset(a, b, sizeof(a))
    27 #define FIN freopen("in.txt", "r", stdin)
    28 #define FOUT freopen("out.txt", "w", stdout)
    29 #define rep(i, a, b) for(int i = a; i <= b; i ++)
    30 #define dec(i, a, b) for(int i = a; i >= b; i --)
    31 
    32 //typedef __int64 LL;
    33 typedef long long LL;
    34 typedef pair<int, int> Pair;
    35 const int MAXN = 300000 + 10;
    36 const int MAXM = 1100000;
    37 const double eps = 1e-12;
    38 LL MOD = 1000000007;
    39 
    40 int n;
    41 struct Node {
    42     int a, id;
    43     bool operator < (const Node &A) const {
    44         return a < A.a;
    45     }
    46 }node[MAXN];
    47 bool vis[MAXN];
    48 
    49 int find_ans(int p, int &mi, int &cnt) {
    50     int sum = 0;
    51     mi = INF;
    52     cnt = 0;
    53     do {
    54         sum += node[p].a;
    55         vis[p] = 1;
    56         cnt ++;
    57         mi = min(mi, node[p].a);
    58         p = node[p].id;
    59     } while(!vis[p]);
    60     return sum;
    61 }
    62 
    63 int main()
    64 {
    65 #ifndef ONLINE_JUDGE
    66     FIN;// FOUT;
    67 #endif
    68     while(~scanf("%d", &n)) {
    69         int mi = INF;
    70         rep (i, 1, n) {
    71             scanf("%d", &node[i].a);
    72             node[i].id = i;
    73             mi = min(mi, node[i].a);
    74         }
    75         sort(node + 1, node + n + 1);
    76         mem0(vis);
    77         int cur_min, cur_cnt, ans = 0;
    78         rep (i, 1, n) if(!vis[i]) {
    79             int sum = find_ans(i, cur_min, cur_cnt); // 找到当前循环的元素个数,最小值
    80             if(cur_cnt > 1) {// mi表示所有数字中的最小值
    81                 ans += sum + min( (cur_cnt - 2) * cur_min, (cur_cnt + 1) * mi + cur_min );
    82             }
    83         }
    84         cout << ans << endl;
    85     }
    86     return 0;
    87 }
  • 相关阅读:
    LightOJ 1132 Summing up Powers(矩阵快速幂)
    hdu 3804 Query on a tree (树链剖分+线段树)
    LightOJ 1052 String Growth && uva 12045 Fun with Strings (矩阵快速幂)
    uva 12304 2D Geometry 110 in 1! (Geometry)
    LA 3263 That Nice Euler Circuit (2D Geometry)
    2013 SCAUCPC Summary
    poj 3321 Apple Tree (Binary Index Tree)
    uva 11796 Dog Distance (几何+模拟)
    uva 11178 Morley's Theorem (2D Geometry)
    动手动脑
  • 原文地址:https://www.cnblogs.com/gj-Acit/p/4713330.html
Copyright © 2020-2023  润新知