奶牛排序 cow sort 置换群
鏈接:https://ac.nowcoder.com/acm/contest/924/H
來源:牛客網(wǎng)
題目描述
農(nóng)夫JOHN準(zhǔn)備把他的 N(1 <= N <= 10,000)頭牛排隊(duì)以便于行動。因?yàn)槠獯蟮呐S锌赡軙v亂,JOHN想把牛按脾氣的大小排序。每一頭牛的脾氣都是一個(gè)在1到100,000之間的整數(shù)并且沒有兩頭牛的脾氣值相同。在排序過程中,JOHN可以交換任意兩頭牛的位置。因?yàn)槠獯蟮呐2缓靡苿?#xff0c;JOHN需要X+Y秒來交換脾氣值為X和Y的兩頭牛。
請幫JOHN計(jì)算把所有牛排好序的最短時(shí)間。
輸入描述:
第1行: 一個(gè)數(shù), N。 第2~N+1行: 每行一個(gè)數(shù),第i+1行是第i頭牛的脾氣值。
輸出描述:
第1行: 一個(gè)數(shù),把所有牛排好序的最短時(shí)間。
示例1
輸入
復(fù)制
3 2 3 1
輸出
復(fù)制
7
第一次接觸這個(gè)概念,一開始沒有什么思路,后來看博客才知道這個(gè)東西就是個(gè)置換問題。
題意:就是一個(gè)亂序的排列通過兩兩置換來達(dá)到升序,每次置換所需的價(jià)格是兩點(diǎn)權(quán)值之和。
思路:首先理解一個(gè)亂序排列存在循環(huán)節(jié),也就是說其中一坨經(jīng)過變換可以達(dá)到他們的升序應(yīng)該的位置,與其他的無關(guān)
例如升序時(shí):?1 2 3 4 5 6?
? ? ? ?亂序時(shí):??4 6 3 1?2?5??
如上所示,41為一個(gè)循環(huán)節(jié),256為一個(gè)循環(huán)節(jié),3為一個(gè)循環(huán)節(jié)
那么對于每一個(gè)長度為n循環(huán)節(jié)的來說最優(yōu)的策略就是用這n個(gè)數(shù)中的最小數(shù)來進(jìn)行n-1次變換,
如上6 2 5 ,就是用2先和5換位置,變成6 5 2,再換2和6那么就是2 5 6 正確的順序。
但是其實(shí)除了循環(huán)節(jié)自身進(jìn)行n-1次置換,還有一種可能最優(yōu)的策略就是拿一個(gè)所有數(shù)中最小的數(shù),與循環(huán)節(jié)里邊的數(shù)進(jìn)行n+1變換,具體自己理解上邊的例子 就是你可以用 1來對上邊的 6 2 5來變換
那么這兩種花費(fèi)分別為 循環(huán)節(jié)里的最小的數(shù)*(循環(huán)節(jié)長度-1)+循環(huán)節(jié)里其他數(shù)的和
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 最小的數(shù)*(循環(huán)節(jié)的長度+2)+循環(huán)節(jié)里所有數(shù)之和
具體看代碼自己模擬理解:
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<math.h>
#include<set>
#include<stack>
#include<vector>
#include<map>
#include<queue>
#include<stdlib.h>
#define myself i,l,r
#define lson i<<1
#define rson i<<1|1
#define Lson i<<1,l,mid
#define Rson i<<1|1,mid+1,r
#define half (l+r)/2
#define inff 0x3f3f3f3f
#define lowbit(x) x&(-x)
#define PI 3.14159265358979323846
#define min4(a,b,c,d) min(min(a,b),min(c,d))
#define min3(x,y,z) min(min(x,y),min(y,z))
#define pii make_pair
#define pr pair<int,int>
const int dir[4][2]={0,1,0,-1,1,0,-1,0};
typedef long long ll;
const ll inFF=9223372036854775807;
typedef unsigned long long ull;
using namespace std;
const int maxn=1e4+5;
int c[maxn],vis[maxn];
int sum=0,minn=inff;
struct node
{int val,id;
}a[maxn];
bool cmp(node s,node e)
{return s.val<e.val;
}
int n;
int dfs(int x)
{vis[x]=1;int cnt=1,val=a[x].val;while(!vis[a[x].id]) //a[x].id就是之前的位置,如果被找過,證明這是一個(gè)循環(huán)節(jié)的結(jié)束{x=a[x].id;vis[x]=1;val=min(val,a[x].val);cnt++;}int c1=(cnt-2)*val;int c2=(cnt+1)*minn+val;return min(c1,c2);
}
int main()
{cin>>n;sum=0,minn=inff;for(int i=1;i<=n;i++){scanf("%d",&a[i].val);a[i].id=i;c[i]=i;sum+=a[i].val;minn=min(minn,a[i].val);}sort(a+1,a+1+n,cmp);for(int i=1;i<=n;i++)if(!vis[i]) sum+=dfs(i);cout<<sum<<endl;
}
?
總結(jié)
以上是生活随笔為你收集整理的奶牛排序 cow sort 置换群的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: POJ - 2387 Til the C
- 下一篇: POJ - 1661 Help Jimm