码迷,mamicode.com
首页 > 编程语言 > 详细

洛谷P2127 序列排序 [贪心]

时间:2018-04-24 14:50:48      阅读:319      评论:0      收藏:0      [点我收藏+]

标签:多少   ++   getc   tps   iostream   min   lse   分析   radius   

  题目传送门

  


 

题目描述

 

小C有一个N个数的整数序列,这个序列的中的数两两不同。小C每次可以交换序列中的任意两个数,代价为这两个数之和。小C希望将整个序列升序排序,问小C需要的最小代价是多少?

 

输入输出格式

输入格式:

 

 

第一行,一个整数N。

 

第二行,N个整数,表示小C的序列。

 

 

输出格式:

 

 

一行,一个整数,表示小C需要的最小代价。

 

 

 

输入输出样例

 

输入样例#1: 复制
6
8 4 5 3 2 7
输出样例#1: 复制
34

 

说明

 

数据范围:

 

对于30%的数据,1<=N<=10;

 

对于全部的数据,1<=N<=100000,输入数据中的其他整数均为正整数且不超过109。

 

 


  

  分析:很显然的贪心。因为每次只能交换两个数,那么每次都拿小的数来交换肯定会更优。但肯定不会这么简单。首先从样例分析,样例中的8,2,7这三个数只要互相交换就可以到达目标位置,也就是说这三个数形成了一个“环”,那么每次就照这样的环,将环中的每一个数归位的最小花费只有两种情况:要么就每次都拿环中最小的数与每一个数相互交换,要么就拿整个序列中最小的数与环中每个数交换。不过要注意,第二种情况交换的时候有一个数会交换两次(可以自己模拟一下),那么肯定就将环中最小的数交换两次最优。具体看代码:

  Code:

 

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cstdlib>
 4 #include<cmath>
 5 #include<iostream>
 6 #include<iomanip>
 7 #include<algorithm>
 8 using namespace std;
 9 const int N=1e5+7;
10 int n;
11 bool vis[N];
12 long long ans;
13 struct Node{
14   int val,pos;
15 }a[N];
16 inline int read()
17 {
18   char ch=getchar();int num=0;bool flag=false;
19   while(ch<0||ch>9){if(ch==-)flag=true;ch=getchar();}
20   while(ch>=0&&ch<=9){num=num*10+ch-0;ch=getchar();}
21   return flag?-num:num;
22 }
23 bool cmp(Node x,Node y)
24 {return x.val<y.val;}
25 inline void work(int x)
26 {
27   long long tot=0,num=0,minn=1e9+7;
28   while(!vis[x]){
29     vis[x]=true;tot++;
30     num+=a[x].val;
31     if(a[x].val<minn)
32       minn=a[x].val;
33     x=a[x].pos;}
34   long long a1=num+(tot-2)*minn;
35   //第一种情况最小的数只需要交换tot-1次
36   long long a2=num+(tot+1)*a[1].val+minn;
37   //第二种情况,如果用整个序列中最小的数交换则需交换(tot-1)次
38   ans+=min(a1,a2);
39 }
40 int main()
41 {
42   n=read();
43   for(int i=1;i<=n;i++){
44     a[i].val=read();
45     a[i].pos=i;}
46   sort(a+1,a+n+1,cmp);
47   for(int i=1;i<=n;i++)
48     if(!vis[i])
49       work(i);
50   printf("%lld",ans);
51   return 0;
52 }

 

洛谷P2127 序列排序 [贪心]

标签:多少   ++   getc   tps   iostream   min   lse   分析   radius   

原文地址:https://www.cnblogs.com/cytus/p/8929775.html

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