您的位置:首页 > 其它

1125 交换机器的最小代价

2017-07-23 08:31 134 查看
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






李陶冶 (题目提供者)

C++的运行时限为:1000 ms ,空间限制为:131072 KB 示例及语言说明请按这里

题解:此题是有关置换群的内容。

1,在置换群里若有t个元素,则至少交换t-1次可以至想要的递增序列(递减序列);

2,据此题要交换代价最小,那么必须以最小的数为媒介进行交换。

3,设在置换群里t-1个元素和为sum1(就是除去了置换群中最小的数minx其他元素的和),

t个元素的和为sum,整个数列中最小的数为mins,

以置换群中最小的数minx为
4000
媒介时,要交换t-1次,说明其他t-1个元素各交换一次,

minx交换t-1次,则代价为sum1+(t-1)*minx=>sum+(t-2)*minx;

以整个数列中最小数mins为媒介时(此时置换群最小的数不是整个数列中最小的),

本就有t个元素,所以要交换t次,说明其他t个元素各交换一次,mins交换t次,

但mins不是置换群里的,所以还要交换回去,因此代价还要加mins+minx, 

则代价为sum+t*mins+mins+minx=>sum+(t+1)*mins+minx;

4,若还感觉有点不明白过程,我就举个列子,给大家模拟一遍。

eg:  7 5 2 4 6 8 1 3  a(原序列,为了方便,我将原序列命名为a,排完序的序列b)

排序后 :1 2 3 4 5 6 7 8  b

置换群有

       :7-1

       
: 5-2-3-8-6

        : 4

现在以第二个置换群的最小值2为媒介对本置换群元素进行交换:

7 5 2 4 6 8 1 3(原序列,为了方便,我将原序列命名为a,排完序的序列b)

7 5 3 4 6 8 1 2 a的2下面是b的3,交换2,3;注意:并排的序列是交换完的序列(以下类同) 

7 5 3 4 6 2 1 8 a的2下面是b的8,交换2,8 ;

7 5 3 4 2 6 1 8 a的2下面是b的6 , 交换2,6;

7 2 3 4 5 6 1 8 a的2下面是b的5,交换2,5;

第二个置换群元素都交换完毕,显然交换了4次,t本就为5,在此开来有t个元素的交换群,

至少交换t-1(其实你可以交换更多次,但没那个必要);

再交换第一个置换群的元素1,7

1 2 3 4 5 6 7 8 所有的交换完毕。

我又将1,2交换,模拟第二种代价的交换过程,其实是类似,所以就从略些;

7 5 2 4 6
8 1 3

7 5
1 4 6 8 2 3

7 5 3 4 6 821

7 5 3 4 6
1 2 8

7 5 3 41 62
8

7 1 3
4 5 6 2 8

7 2 3 4 5 6 1 8 再换回1,2,这就是为什么要在第二种的代价后再加mins+minx的原因。

1 2 3 4 5 6 7 8

由于mins+minx大小不确定,所以才比较第一种代价sum+(t-2)*minx和

第二种代价sum+(t+1)*mins+minx谁更小,就选谁。

就是说,若以mins为minx得到的代价sum+(t-2)*mins肯定小于等于sum+(t-2)*minx,

但交换mins和minx也需要代价x,所以sum+(t-2)*mins+x=>sum+(t+1)*mins+minx与

sum+(t-2)*minx大小就不确定了,进一步看谁更小,就选谁。

具体代码如下:

#include <bits/stdc++.h>
#define LL long long
using namespace std;
struct node
{
LL va;
int id;
};
bool cmp (node a,node b)
{
return a.va<b.va;
}
int main ()
{
int n;
node w[50005];
LL mins=9999999,minx=9999999,a[50005];  //mins为整个数列中最小的,minx为当前置换群中最小的。
LL sum=0;
cin>>n;
for (int i=0;i<n;i++)
{
scanf("%lld",&a[i]);
w[i].va=a[i];
w[i].id=i;
sum+=a[i];
mins=min(mins,a[i]);
}

sort(w,w+n,cmp);
int f[50005]={0};
for (int i=0;i<n;i++)
{
if(!f[i])
{
int j=i;
int t=0;
minx=a[j];
while(!f[j])
{
t++;
f[j]=1;
minx=min(a[j],minx);
j=w[j].id;//通过id去寻找置换群里的下一个元素
}
sum+=min((t-2)*minx,(t+1)*mins+minx);//比较这两种代价谁更小则选谁。
}
}
printf("%lld",sum);
return 0;
}


类似:poj
Cow Sorting 3270(同一代码可以AC)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  置换群 贪心 51nod