zoukankan      html  css  js  c++  java
  • poj 3270(置换群+贪心)

    Cow Sorting
    Time Limit: 2000MS   Memory Limit: 65536K
    Total Submissions: 6993   Accepted: 2754

    Description

    Farmer John's N (1 ≤ N ≤ 10,000) cows are lined up to be milked in the evening. Each cow has a unique "grumpiness" level in the range 1...100,000. Since grumpy cows are more likely to damage FJ's milking equipment, FJ would like to reorder the cows in line so they are lined up in increasing order of grumpiness. During this process, the places of any two cows (not necessarily adjacent) can be interchanged. Since grumpy cows are harder to move, it takes FJ a total of X+Y units of time to exchange two cows whose grumpiness levels are X and Y.

    Please help FJ calculate the minimal time required to reorder the cows.

    Input

    Line 1: A single integer: N.
    Lines 2..N+1: Each line contains a single integer: line i+1 describes the grumpiness of cow i.

    Output

    Line 1: A single line with the minimal time required to reorder the cows in increasing order of grumpiness.

    Sample Input

    3
    2
    3
    1

    Sample Output

    7

    Hint

    2 3 1 : Initial order.
    2 1 3 : After interchanging cows with grumpiness 3 and 1 (time=1+3=4).
    1 2 3 : After interchanging cows with grumpiness 1 and 2 (time=2+1=3).

    Source

     
    题意:给出 n 头牛,每头牛有一个脾气值,现在可以交换任意两头牛,交换它们的代价是两者脾气之和,问现在要将这些牛的脾气变成一个升序序列最少需要的代价?
    题解:这个题让我接触到一个新的东西,置换群:
    http://pic002.cnblogs.com/images/2012/419571/2012062114092428.png
    比如上图:可以看出有两个群 1->6->5->1, 2->3->4->2
    分别是 (1,6,5)和(2,3,4)
    然后我们对于每个群将里面的元素交换的代价有两种方式:
    这里每一个置换群里面的数归位有两种方法:
    一种是利用该群里面最小的那个元素将所有的元素归位:
    设当前群的循环节为 n,这里最小的那个数总共需要交换n-1 次,其余的数各需要一次.
    这里所需要的代价是 val = sum(该群内元素之和) - 该群最小的元素 + (loop-1)*该群的最小元素;

    另外一种当时是利用整个集合内最小的元素将该群所有的元素归位,先需要交换整个集合最小元素(m1)与该群
    最小元素(m2),然后再利用 m1 与各元素交换一次,m1总共交换了 loop 次,最后要将 m2换回来,所以 m1 交换了
    loop+1次,m2交换了两次,其余元素各交换了一次.
    /**
    置换:
        这里每一个置换群里面的数归位有两种方法:
        一种是利用该群里面最小的那个元素将所有的元素归位:
        设当前群的循环节为 n,这里最小的那个数总共需要交换n-1 次,其余的数各需要一次.
        这里所需要的代价是 val = sum(该群内元素之和) - 该群最小的元素 + (loop-1)*该群的最小元素;
    
        另外一种当时是利用整个集合内最小的元素将该群所有的元素归位,先需要交换整个集合最小元素(m1)与该群
        最小元素(m2),然后再利用 m1 与各元素交换一次,m1总共交换了 loop 次,最后要将 m2换回来,所以 m1 交换了
        loop+1次,m2交换了两次,其余元素各交换了一次.
    **/
    #include <stdio.h>
    #include <algorithm>
    #include <string.h>
    using namespace std;
    typedef long long LL;
    const int N = 10005;
    const int INF = 1e18;
    struct Node{
        int val;
        int id;
    }node[N];
    int m1,m2,loop,n;
    bool vis[N];
    LL solve(){
        LL res = 0,sum;
        for(int i=1;i<=n;i++){
            m2 = INF;
            sum = loop = 0;
            int t = i;
            while(!vis[t]){
                vis[t] = true;
                loop++;
                m2 = min(m2,node[t].val);
                sum+=node[t].val;
                t = node[t].id;
            }
            if(loop){
                res = res+min(sum-m2+(loop-1)*m2,sum+m2+(loop+1)*m1);
            }
        }
        return res;
    }
    int cmp(Node a,Node b){
        return a.val < b.val;
    }
    int main()
    {
        while(scanf("%d",&n)!=EOF){
            m1 = INF;
            memset(vis,false,sizeof(vis));
            for(int i=1;i<=n;i++){
                scanf("%d",&node[i].val);
                node[i].id = i;
                m1 = min(m1,node[i].val);
            }
            sort(node+1,node+1+n,cmp);
            printf("%lld
    ",solve());
        }
        return 0;
    }
  • 相关阅读:
    Python中的unittest和logging
    android短彩信附件机制
    Android Mms之:深入MMS支持
    Android 源码阅读之SMS,MMS
    深度分析:Android4.3下MMS发送到附件为音频文件(音频为系统内置音频)的彩信给自己,添加音频-发送彩信-接收彩信-下载音频附件-预览-播放(一,添加附件)
    使用adb命令对手机进行截屏保存到电脑,SDCard
    Android中检测字符编码(GB2312,ASCII,UTF8,UNICODE,TOTAL——ENCODINGS)方法(二)
    解决新建短信时,输入“+86”,然后输入联系人名字“1”,按删除键之后,联系人变为“1”,删除操作为达到预期结果
    解决:People下面选择分享可见联系人,选择多个联系人后通过短信分享,短信中只显示一个联系人
    解决:短信添加录音附件,录音,没有录音时间限制,超出彩信最大限制也正常录音
  • 原文地址:https://www.cnblogs.com/liyinggang/p/5967032.html
Copyright © 2011-2022 走看看