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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zjw6463/article/details/51953678
1125 交换机器的最小代价
基准时间限制: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
3
2
1
Output示例
4


思路:首选要交换么,所以第一步肯定要给它排序,因为是贪心么,又要求最小代价,所以要尽可能的让小的多交换。如果一个机器和它的位置不对应,那么它肯定要交换的

两种方案:

第一种、从小到大开始, 如果这个机器不在正确的位置,那就和应该在这位置的机器交换,直到交换到自己的位置

假设交换了x次, 起始的值为a, 那么最后的代价为x * a + 其它参与交换的值

第二种、就是一直通过所有的值中最小的值mx来进行交换,先让mx和当前的值a交换,然后按照一方案交换, 最后再把mx交换到第一位置,所以这方案的次数要比一方案的次数多2次,所以为x + 2, 所以这个的代价为

(x + 2) * mx + 2 * a +其他参与交换的值,

最后只要取这两种方案的最小值加进去即可


#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <string>
#include <functional>
#include <cmath>
#include <set>
#include <queue>
#include <algorithm>
#include <vector>
#include <map>
#include <stack>
using namespace std;
#define esp  1e-8
const double PI = acos(-1.0);
const double e = 2.718281828459;
const int inf = 2147483647;
const long long mod = 1000000007;
typedef long long ll;
//freopen("in.txt","r",stdin); //输入重定向,输入数据将从in.txt文件中读取
//freopen("out.txt","w",stdout); //输出重定向,输出数据将保存在out.txt文件中
ll a[50005], b[50005];
map<ll, ll>mp;
ll s;
ll tep;
void dfs(int pre, int pos, int sta)
{
	s += pre + a[pos];
	tep ++;
	//cout << pre << " " << a[pos] << endl;
	int p = mp[a[pos]];
	mp[a[pos]] = pos;
	mp[pre] = p;
	if (mp[pre] != sta)
	{
		dfs(pre, p, sta);
	}
}
int main()
{
	int n, i, j;
	cin >> n;
	for (i = 1; i <= n; ++i)
	{
		cin >> a[i];
		mp[a[i]] = i;
		b[i] = a[i];
	}
	sort(a + 1, a + 1 + n);
	ll sum = 0;
	for (i = 1; i <= n; ++i)
	{
		if (mp[a[i]] != i)
		{
			s = 0;
			tep = 0;
			dfs(a[i], mp[a[i]], i);
			sum += min(s, s + (2LL - tep) * a[i] + (tep + 2LL) * a[1]);
		}
	}
	cout << sum << endl;
}


猜你喜欢

转载自blog.csdn.net/zjw6463/article/details/51953678
今日推荐