标签:
题意:有N头牛,每头牛都有不同的暴躁值ai,现在要将所有的牛按照暴躁值从小到大排序,每次交换两个元素(任意交换)时,花费就是两头牛的暴躁值之和;问排序的最小花费为多少?
数据:(1 ≤ N ≤ 10,000) (1 <= ai <= 100,000);
思路:很明显的贪心;(下面讲的循环是置换群里的循环)
策略:我们从没在最终位置且值最小的牛看起,如果每次都是将当前考虑的牛直接与它最终的位置的牛交换,那么这样递推下去,将形成的就是一个循环(一定有牛的最终位置为考虑的起始位置,这是这个循环结束了);
在每一个循环中,由于所有的值都是需要交换的,所以以贪心的思想,每次用最小的牛去交换,值大的牛只交换一次~~,那么这就是循环自己调整的花费的最小值。但是这个策略并没有考虑到用循环外的牛来调整循环里的牛的次序,并且当存在一个循环之外值很小的牛时,用这个牛来调整这个循环里的牛显然花费更低~~;每个循环只需取二者较小的即可;
#include<iostream> #include<cstdio> #include<cstring> #include<string.h> #include<algorithm> #include<vector> #include<cmath> #include<stdlib.h> #include<time.h> #include<stack> #include<set> #include<map> #include<queue> using namespace std; #define rep0(i,l,r) for(int i = (l);i < (r);i++) #define rep1(i,l,r) for(int i = (l);i <= (r);i++) #define rep_0(i,r,l) for(int i = (r);i > (l);i--) #define rep_1(i,r,l) for(int i = (r);i >= (l);i--) #define MS0(a) memset(a,0,sizeof(a)) #define MS1(a) memset(a,-1,sizeof(a)) #define MSi(a) memset(a,0x3f,sizeof(a)) #define inf 0x3f3f3f3f #define lson l, m, rt << 1 #define rson m+1, r, rt << 1|1 typedef pair<int,int> PII; #define A first #define B second #define MK make_pair typedef __int64 ll; template<typename T> void read1(T &m) { T x=0,f=1;char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} m = x*f; } template<typename T> void read2(T &a,T &b){read1(a);read1(b);} template<typename T> void read3(T &a,T &b,T &c){read1(a);read1(b);read1(c);} template<typename T> void out(T a) { if(a>9) out(a/10); putchar(a%10+‘0‘); } int vis[10010],vec[10010];//没有使用vector,只用一维即可 PII B[10010]; int mn,num; int solve() { int ans = 0; rep0(i,0,num) ans += mn + vec[i]; ans += vec[0] + mn; return ans; } int main() { int n,ans = 0,cnt = 0; mn = inf; read1(n); rep1(i,1,n) read1(B[i].A),B[i].B = i,mn = min(mn,B[i].A); sort(B+1,B+1+n); rep1(i,1,n)if(!vis[i]){ int tmp = i; ++cnt;num = 0; do{ vis[tmp] = 1; vec[num++] = B[tmp].A; tmp = B[tmp].B; }while(!vis[tmp]); if(num == 1) continue; sort(vec,vec + num); tmp = 0; rep0(j,1,num) tmp += vec[j]; tmp += (num - 1)*vec[0]; ans += min(tmp,solve()); } printf("%d\n",ans); return 0; }
标签:
原文地址:http://www.cnblogs.com/hxer/p/5223472.html