题意:
给长度为N的学列,然后让你通过置换来使其递增。原序列没有相同的数字。
1 ≤ N ≤ 10,000
ai<=100000
思路:
先找到循环,然后根据贪心只有两种比较好的情况,让循环里边最小的数作为循环的起点,或者在循环外边找到最小的数作为置换的起点。
坑点:
wa三次的原因是循环外的那个公式写错...因为最后还是要多换一次的...
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; long long jilu[10050]; long long xu[10050]; long long sum[10050]; long long mmin[10050]; long long num[10050]; bool vis[10050]; bool rel[10050]; int main() { int n; scanf("%d",&n); for(int i=0;i<n;i++){ scanf("%I64d",jilu+i); xu[i]=jilu[i]; } sort(xu,xu+n); for(int i=0;i<n;i++){ if(!vis[i]){ rel[i]=1; sum[i]=mmin[i]=jilu[i]; num[i]=1; int tt=i; while(upper_bound(xu,xu+n,jilu[tt])-xu-1!=i){ tt=upper_bound(xu,xu+n,jilu[tt])-xu-1; vis[tt]=1; sum[i]+=jilu[tt]; mmin[i]=min(mmin[i],jilu[tt]); num[i]++; } } } long long ans=0; for(int i=0;i<n;i++){ if(rel[i]){ ans+=min((num[i]-1)*mmin[i]+sum[i]-mmin[i],xu[0]*num[i]+sum[i]+xu[0]+mmin[i]); } } printf("%I64d ",ans); }