农夫JOHN准备把他的 N(1 <= N <= 10,000)头牛排队以便于行动。因为脾气大的牛有可能会捣乱,JOHN想把牛按脾气的大小排序。每一头牛的脾气都是一个在1到100,000之间的整数并且没有两头牛的脾气值相同。在排序过程中,JOHN 可以交换任意两头牛的位置。因为脾气大的牛不好移动,JOHN需要X+Y秒来交换脾气值为X和Y的两头牛。 请帮JOHN计算把所有牛排好序的最短时间。
标签:ons nbsp tin 队列 log 最小值 两种 www. discuss
农夫JOHN准备把他的 N(1 <= N <= 10,000)头牛排队以便于行动。因为脾气大的牛有可能会捣乱,JOHN想把牛按脾气的大小排序。每一头牛的脾气都是一个在1到100,000之间的整数并且没有两头牛的脾气值相同。在排序过程中,JOHN 可以交换任意两头牛的位置。因为脾气大的牛不好移动,JOHN需要X+Y秒来交换脾气值为X和Y的两头牛。 请帮JOHN计算把所有牛排好序的最短时间。
第1行: 一个数, N。
第2~N+1行: 每行一个数,第i+1行是第i头牛的脾气值。
第1行: 一个数,把所有牛排好序的最短时间。
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; char buf[10000000], *ptr = buf - 1; inline int readint(){ int n = 0; char ch = *++ptr; while(ch < ‘0‘ || ch > ‘9‘) ch = *++ptr; while(ch <= ‘9‘ && ch >= ‘0‘){ n = (n << 1) + (n << 3) + ch - ‘0‘; ch = *++ptr; } return n; } typedef long long ll; const int maxn = 10000 + 10; int num[maxn], pos[maxn], a[maxn]; bool vis[maxn] = {false}; int main(){ fread(buf, sizeof(char), sizeof(buf), stdin); int N = readint(); for(int i = 1; i <= N; i++) num[i] = a[i] = readint(); sort(a + 1, a + N + 1); for(int i = 1; i <= N; i++) pos[i] = lower_bound(a + 1, a + N + 1, num[i]) - a; ll ans = 0; for(int j, Min, tot, siz, i = 1; i <= N; i++){ if(vis[i]) continue; Min = tot = num[i]; siz = 1; vis[i] = true; j = pos[i]; while(!vis[j]){ Min = min(Min, num[j]); tot += num[j]; siz++; vis[j] = true; j = pos[j]; } ans += min((ll)Min * (siz - 2), (ll)a[1] * (siz + 1) + Min) + tot; } printf("%lld\n", ans); return 0; }
[BZOJ1697][Usaco2007 Feb]Cow Sorting牛排序
标签:ons nbsp tin 队列 log 最小值 两种 www. discuss
原文地址:http://www.cnblogs.com/ruoruoruo/p/7553259.html