• poj3270Cow Sorting(置换+贪心)


    Cow Sorting
    Time Limit: 2000MS   Memory Limit: 65536K
    Total Submissions: 7587   Accepted: 2982

    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).
    /*
    * @Author: LyuC
    * @Date:   2017-10-12 15:55:54
    * @Last Modified by:   LyuC
    * @Last Modified time: 2017-10-12 16:52:18
    */
    /*
     题意:给你一个无序的序列,让你只能两两进行交换,使得序列有序,每次操作的代价是两个数的和
        问你最少的代价是多少
    
     思路:置换+贪心
        例子 :
            原始序列:1 8 9 7 6
            排序下标:1 4 5 3 2
                那么我们发现,位置不对的8 9 7 6实际上是一个置换:4->3->5->2->4
            长度为4最少需要交换三次才能使得序列有序,保证了次数最少了,然后就是
            考虑怎么交换才能代价最小,置换(4,3,5,2)可以拆成(2,4),(2,3),(2,5),
            这样就保证了部分交换代价是最小的,但是这个例子就是个特例,如果首先
            将1 6 进行交换使得(4,3,5,1)在一个置换里,交换完再用6把1交换出去,这
            样的代价更小,所以这个有两种最优操作,处理的时候取两者更右者;
    */
    #include <iostream>
    #include <stdio.h>
    #include <vector>
    #include <string.h>
    #include <algorithm>
    
    #define MAXN 10005
    #define INF 0x3f3f3f3f
    
    using namespace std;
    
    struct Node{
        int val;
        int index;
        int sortindex;
    }a[MAXN];
    int n;
    bool vis[MAXN];
    vector<int>v[MAXN];
    int pos;
    int minnum;
    
    bool cmp1(Node a,Node b){
        return a.val<b.val;
    }
    
    bool cmp2(Node a,Node b){
        return a.index<b.index;
    }
    
    void init(){
        for(int i=0;i<MAXN;i++)
            v[i].clear();
        pos=0;
        minnum=INF;
        memset(vis,false,sizeof vis);
    }
    
    int main(){
        // freopen("in.txt","r",stdin);
        while(scanf("%d",&n)!=EOF){
            init();
            for(int i=1;i<=n;i++){
                scanf("%d",&a[i].val);
                a[i].index=i;
                minnum=min(minnum,a[i].val);
            }
            sort(a+1,a+n+1,cmp1);
            for(int i=1;i<=n;i++){
                a[i].sortindex=i;
            }
            sort(a+1,a+n+1,cmp2);
            for(int i=1;i<=n;i++){
                if(vis[i]==true)
                    continue;
                int x=i;
                vis[i]=true;
                v[pos].push_back(a[i].sortindex);
                x=a[x].sortindex;
                while(x!=i){
                    if(vis[x]==true){
                        break;
                    }
                    v[pos].push_back(a[x].sortindex);
                    vis[x]=true;
                    x=a[x].sortindex;
                }
                if(a[x].sortindex==a[i].sortindex){
                    pos++;
                }else{
                    v[pos].clear();
                    v[pos].push_back(i);
                    int End=x;
                    x=i;
                    vis[x]=false;
                    while(x!=End){
                        x=a[x].sortindex;
                        vis[x]=false;
                    }
                    vis[i]=true;
                    pos++;
                }
            }
            sort(a+1,a+n+1,cmp1);
            int res=0,ra,rb;
            for(int i=0;i<pos;i++){
                sort(v[i].begin(),v[i].end());
                ra=0;
                for(int j=1;j<(int)v[i].size();j++){
                    ra+=(a[v[i][0]].val+a[v[i][j]].val);
                }
                if(minnum!=a[v[i][0]].val){
                    rb=0;
                    for(int j=1;j<(int)v[i].size();j++){
                        rb+=(minnum+a[v[i][j]].val);
                    }
                    rb+=2*(minnum+a[v[i][0]].val);
                }else{
                    rb=INF;
                }
                res+=min(ra,rb);
            }
            printf("%d
    ",res);
        }
        return 0;
    }
  • 相关阅读:
    WikiPedia技术架构学习笔记
    MySQL 架构设计篇 (十二) 可扩展设计的基本原则
    php前端控制器二
    php前端控制器三
    构建可扩展的WEB站点读书笔记
    发布脚本开发框架代码
    改良dbgrideh的文字过滤
    cxgrid在当前View插入记录
    生成不重复单据编号
    cxgrid按条件计算合计值
  • 原文地址:https://www.cnblogs.com/wuwangchuxin0924/p/7656934.html
Copyright © 2020-2023  润新知