• 数学:置换群-轮换计数(1)


    BZOJ1697:置换群的轮换计数

    把牛排序,只能每次交换两个牛的位置,代价为这两个牛的脾气之和

    问最小交换代价

    交换的原始序列是输入序列,目标序列是有序的序列

    我们求出每一个轮换,记录每一个轮换的信息,考虑两种情况然后计数就可以了

     1 //对于其中一个循环
     2 //sum + (len – 2) * min 
     3 //sum为这个循环所有数字的和,len为长度,min为这个环里面最小的数字
     4 
     5 //sum + min + (len + 1) * smallest
     6 //sum为这个循环所有数字的和,len为长度,min为这个环里面最小的数字,smallest是整个数列最小的数字
     7 #include<cstdio>
     8 #include<algorithm>
     9 #include<cstring>
    10 #define INF 0x7f7f7f7f
    11 using namespace std;
    12 const int maxn=10005;
    13 int n,vmin,cnt,ans;
    14 int v[maxn],dis[maxn],vis[maxn],len[maxn],sum[maxn],id[maxn],mn[maxn];
    15 int read()
    16 {
    17     int x=0,f=1;char ch=getchar();
    18     while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
    19     while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
    20     return x*f;
    21 }
    22 int find(int x)  //有序,二分查找x的最终位置 
    23 {
    24     int l=1,r=n;
    25     while(l<=r)
    26     {
    27         int mid=(l+r)>>1;
    28         if(dis[mid]>x) r=mid-1;
    29         else if(dis[mid]==x) return mid;
    30         else l=mid+1;
    31     }
    32     return -1;
    33 }
    34 void solve(int x)  //处理轮换 
    35 {
    36     vis[x]=1;cnt++;
    37     len[cnt]=1;sum[cnt]+=v[x];mn[cnt]=min(mn[cnt],v[x]); 
    38     int now=x;
    39     while(v[id[now]]!=v[x])
    40     {
    41         now=id[now];vis[now]=1;
    42         len[cnt]++;sum[cnt]+=v[now];mn[cnt]=min(mn[cnt],v[now]);
    43     }
    44 }
    45 void init()
    46 {
    47     vmin=INF;
    48     memset(mn,127/3,sizeof(mn));
    49 }
    50 int main()
    51 {
    52     init();
    53     n=read();
    54     for(int i=1;i<=n;i++)
    55     {
    56         v[i]=read();
    57         dis[i]=v[i];
    58         vmin=min(vmin,v[i]);
    59     }
    60     sort(dis+1,dis+n+1);
    61     for(int i=1;i<=n;i++) id[i]=find(v[i]);  //id每一个元素的最终位置 
    62     for(int i=1;i<=n;i++)
    63     if(!vis[i]&&i!=id[i]) solve(i);
    64     for(int i=1;i<=cnt;i++)
    65     {
    66         int t1=(len[i]-2)*mn[i];
    67         int t2=mn[i]+(len[i]+1)*vmin;
    68         ans+=sum[i]+min(t1,t2);
    69     } 
    70     printf("%d",ans);
    71     return 0;
    72 }
  • 相关阅读:
    asp.net core mvc 之 DynamicApi
    打造适用于c#的feign
    asp.net App_Code文件夹相关操作
    基于Mono.Cecil的静态注入
    补充ICache
    自制简单实用IoC
    自制简单的.Net ORM框架 (一) 简介
    解决Asp.net Mvc中使用异步的时候HttpContext.Current为null的方法
    微信开发之.Net
    VS2017 网站打包发布生成的文件中包含.pdb文件,解决办法
  • 原文地址:https://www.cnblogs.com/aininot260/p/9695885.html
Copyright © 2020-2023  润新知