zoukankan      html  css  js  c++  java
  • poj 3270 更换使用

    1.确定的初始状态和目标状态。清除,目标状态是整理后的状态。

    2.绘制置换群,获取内部循环。例如,8 4 5 3 2 7,目标状态是2 3 4 5 7 8。能写为两个循环:(8 2 7)(4 3 5)

    3.观察当中一个循环,明显地。要使交换代价最小。应该用循环里面最小的数字2,去与另外的两个数字,78交换。

    这样交换的代价是:

    sum - min + (len - 1) * min

    化简后为:

    sum + (len - 2) * min

    当中,sum为这个循环全部数字的和。len为长度,min为这个环里面最小的数字。

    4.考虑到第二种情况。我们能够从别的循环里面调一个数字。进入这个循环之中,使交换代价更小。比如初始状态:1 8 9 7 6

    可分解为两个循环:(1)(8 6 9 7),明显。第二个循环为(8 6 9 7)。最小的数字为6。我们能够抽调整个数列最小的数字1进入这个循环。使第二个循环变为:(8 1 9 7)。让这个1完毕任务后,再和6交换,让6又一次回到循环之后。

    这样做的代价明显是:

    sum + min + (len + 1) * smallest

    当中。sum为这个循环全部数字的和。len为长度。min为这个环里面最小的数字,smallest是整个数列最小的数字。

    5.因此,对一个循环的排序。其代价是sum - min + (len - 1) * minsum + min + (len + 1) * smallest之中小的那个数字。但这里两个公式还不知道怎么推出来的。

    6.我们在计算循环的时候。不须要记录这个循环的全部元素,仅仅须要记录这个循环的最小的数及其和。

    7.在储存数目的时候,我们能够使用一个hash结构,将元素及其位置相应起来。以达到知道元素。能够高速反查元素位置的目的。

    这样就不必要一个个去搜索。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int maxn = 10010;
    
    int a[maxn],b[maxn],dir[100005];
    int vis[maxn];
    int main()
    {
        int n;
        while(scanf("%d",&n) != EOF){
            for(int i = 0; i < n; i++){
                scanf("%d",&a[i]);
                b[i] = a[i];
                dir[a[i]] = i;
            }
            sort(b,b+n);
            memset(vis,0,sizeof(vis));
            int ans = 0;
            for(int i = 0; i < n; i++){
                if(!vis[i]){
                    vis[i] = 1;
                    int id = i,start = a[i];
                    int len = 1,min_ = a[i],sum = a[i];
                    
                    ///找出置换的循环;
                    while(1){
                        if(b[id] == start) break;
                        sum += b[id];
                        len ++;
                        min_ = min(min_,b[id]);
                        id = dir[b[id]];
                        vis[id] = 1;
                    }
                    
                    ///求出在当前这个循环中的最小花费;
                    int tmp = min(min_*(len-1) + sum-min_, b[0]*(len+1) + sum + min_);
                    ans += tmp;
                }
    
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    


    版权声明:请注明出处撒...http://blog.csdn.net/u013382399

  • 相关阅读:
    hdu2328 Corporate Identity
    hdu1238 Substrings
    hdu4300 Clairewd’s message
    hdu3336 Count the string
    hdu2597 Simpsons’ Hidden Talents
    poj3080 Blue Jeans
    poj2752 Seek the Name, Seek the Fame
    poj2406 Power Strings
    hust1010 The Minimum Length
    hdu1358 Period
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/4913808.html
Copyright © 2011-2022 走看看