51NOD1125交换机器的最小代价(贪心算法)

原题如下:

有N台机器重量各不相等,现在要求把这些机器按照重量排序,重量从左到右依次递增。移动机器只能做交换操作,但交换机器要花费一定的费用,费用的大小就是交换机器重量的和。例如:3 2 1,交换1 3后为递增排序,总的交换代价为4。给出N台机器的重量,求将所有机器变为有序的最小代价。(机器的重量均为正整数)
Input
第1行:1个数N,表示机器及房间的数量。(2 <= N <= 50000)
第2 - N + 1行:每行1个数,表示机器的重量Wi。(1 <= Wi <= 10^9)
Output
输出最小代价。
Input示例
3
3
2
1
Output示例
4


思路:感觉是比较有意思的贪心题目。想了很久不得要领。仔细在纸上分析之后找到了方法。

因为你最后是要变为有序状态。所有原来的位置和有序状态的位置不同的机器肯定是要做交换。

那么针对每一个机器怎样交换的代价最小?很容易想到尽可能的使重量小的机器交换次数多,重量大的物品交换次数少

所以策略就是两种,我们把机器按重量从小到大排序,并记录下它原始的位置。从小到大遍历。把某个重量的机器放到它应该在的位置上,必然要把占了这个位置的机器也做移动,依此类推下去。

第一种策略:用这些机器(假如为x个)中重量最小的依此和需要交换的机器交换。这种情况下,其它所有机器交换一次,最小重量的机器交换x次。

第二种策略:用所有机器中重量最小的依此和这些机器交换。再把重量最小的换回到第一个位置。这种情况下,重量最小的那个交换x+2(换出去换回来各一次)次,其他的交换一次.但有一个特殊的,最后把最小的那个交换回来的要多交换一次。也就是两次。我们自然会选取重量最小的那个作为特殊机器。

#include
#include
#include
#include 
#include 
#include 
#define MAXN 50010
using namespace std;
struct mac{
    int initial;//原来的位置
    int weight;//机器的重量
};
mac M[MAXN];
int cmp(mac a,mac b)
{
    return a.weight>n;
    for(int i=1;i<=n;i++)
    {
        cin>>M[i].weight;
        M[i].initial=i;
    }
    sort(M,M+n+1,cmp);
    least=M[1].weight;
    for(int i=1;i<=n;i++)
    {
        if(!vis[i])
        {
            cost+=solve(i);
        }
    }
    printf("%lld\n",cost);
}



你可能感兴趣的:(算法,贪心算法)