1125 交换机器的最小代价 51NOD

基准时间限制:1 秒 空间限制:131072 KB 分值: 80  难度:5级算法题
有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
题目大意:
交换机器,给定若干机器,请按照机器重量给排序,方式为机器两两互换,交换依次记录下交换重量,
思考一下及其交换怎么贪心才能让交换所得总重量最小呢,无非就是重量小的尽量多换几次,重量大的一步就位;
可以定义结构体,记录一下机器重量和他原来在的位置,然后排序,按照升序的方式打乱机器顺序;
分析题意,可以发现一个有趣的现象,当机器的数量越来越多时,可能会发生几个机器的交换仅仅局限在这几个机器之间,不会干扰到别的机器;
这样就可以把机器分成几个小组,小组成员互相交换达到平衡(可以看成一个环)
举个栗子:
			5 5 , 2   , 44  ,  1  ,  33
顺序:       1             2         3         4       5
排序后:1 , 2, 	33,	44,	55
顺序:   4	2	5	3	1
1--》44--》33--》55--》1
这样就连成了一个环,把1依次和55,33,44换一下,1换了3次 55,33,44换了一次,即使最好的情况,
除此之外,当环内不包含最小元素时还要考虑是否把环内的最小元素换为所有元素的最小元素,用所有元素的最小元素代替环内最小元素来进行替换,
比较一下这两种情况,去最小的交换总重量,就是本题的最优解;
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
struct Mechine{
	long long number;
	long long weight;
	int flag;
}pm[50010];
bool cmp(Mechine x,Mechine y)
{
	return x.weight<y.weight;
}
int main()
{
	long long n;
	while(scanf("%d",&n)!=EOF)
	{
		int i;
		long long _max=0, sum=0,count;
		for(i=0;i<n;i++)
		{
			scanf("%lld",&pm[i].weight);
			pm[i].number=i;
			pm[i].flag=0; 
		}
		sort(pm,pm+n,cmp);
		long long _min=pm[0].weight;
	for(i=0;i<n;i++)
		{
			
			if(!pm[i].flag)
			{
				count=0,sum=0;
				int k=i;
				pm[i].flag=1;
				while(i!=pm[k].number)//i是蛇头 k是蛇的节点 
				{
			pm[pm[k].number].flag=1;
				sum+=pm[pm[k].number].weight;
				k=pm[k].number;
				count++;
				}
			_max+=sum+min((count*pm[i].weight),((count+2)*_min+pm[i].weight*2));
			}
		}
	printf("%lld\n",_max);
	}
return 0;	
} 

321
Output示例
4
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值