码迷,mamicode.com
首页 > 其他好文 > 详细

[ACM] POJ 3270 Cow Sorting (置换,贪心)

时间:2014-07-27 11:19:42      阅读:354      评论:0      收藏:0      [点我收藏+]

标签:acm   置换   

Cow Sorting
Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 5946   Accepted: 2263

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只牛,每只牛都有自己的坏脾气值,现在要把这N只牛按照坏脾气值从小到大排序,每一次交换的代价定义为被交换的两头牛的坏脾气值之和,问最小的代价是多少。

刘汝佳黑书上的例题(P247 无聊的排序是和这个一样的)。下面是书上作者给的解题思路,用到了贪心和置换的知识,很好懂:

bubuko.com,布布扣

输入的数原来的位置是按输入顺序,1,2,3,4.n的,排完序后用pos[]数组记下这些数新的位置,然后再找循环节,每一个循环节都进行上面说的两种操作,取最小值,结果累加。


代码:

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
using namespace std;
const int maxn=100010;
int val[maxn];
int temp[maxn];//备用数组,排序前
int pos[maxn];//排序后的位置
bool vis[maxn];//找循环节看是否被访问过。
int MIN=0x7fffffff;//全局最小值
int Min;//每个循环节的最小值
int n;//牛的头数
int ans=0;

int main()
{
    memset(vis,0,sizeof(vis));
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&val[i]);
        temp[i]=val[i];
        if(MIN>val[i])
            MIN=val[i];
    }
    sort(val+1,val+1+n);
    for(int i=1;i<=n;i++)
        pos[val[i]]=i;//排序后各元素所在的位置
    //找循环节
    for(int i=1;i<=n;i++)
    {
        if(!vis[i])
        {
            int cnt=0;//循环节的长度
            int label=i;//循环节里面的元素,label始终代表原始输入的时候是第几个数。
            int sum=0;//循环节里面元素和
            Min=temp[label];
            while(!vis[label])
            {
                vis[label]=1;
                cnt++;
                Min=min(Min,temp[label]);
                sum+=temp[label];
                label=pos[temp[label]];
            }
            ans+=(sum+min((cnt-2)*Min,Min+(cnt+1)*MIN));
        }
    }
    cout<<ans;
    return 0;
}


[ACM] POJ 3270 Cow Sorting (置换,贪心)

标签:acm   置换   

原文地址:http://blog.csdn.net/sr_19930829/article/details/38166667

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!