zoukankan      html  css  js  c++  java
  • 排序

    题意:给出一个长为n的序列a,每次可以交换两个元素,代价为其之和,求最小总代价使得序列变为升序。

    这几天怎么净看见神题了...

    这题考群论思想...

    考虑一个循环节,有两种把它归位的方式,一种是用循环内的最小值去挪移每个值,另一种是用全局最小值去挪移每个值

    思路出来以后就ok了,真是一道神题啊qaq...

    哦对要离散化

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<cstdlib>
    #include<ctime>
    using namespace std;
    inline int read()
    {
        int ans = 0,op = 1;
        char ch = getchar();
        while(ch < '0' || ch > '9')
        {
            if(ch == '-') op = -1;
            ch = getchar();
        }
        while(ch >= '0' && ch <= '9')
        {
            (ans *= 10) += ch - '0';
            ch = getchar();
        }
        return ans * op;
    }
    typedef int mainint;
    #define int long long 
    const int inf = 0x7f7f7f7f;
    const int maxn = 2e5 + 5;
    int a[maxn],tp[maxn];
    int to[maxn];
    int minm = inf;
    bool vis[maxn];
    int ans;
    mainint main()
    {
      int n = read();
      for(int i = 1;i <= n;i++) a[i] = read(),tp[i] = a[i],minm = min(minm,a[i]);
      sort(tp + 1,tp + 1 + n);
      for(int i = 1;i <= n;i++) to[i] = lower_bound(tp + 1,tp + 1 + n,a[i]) - tp; 
      for(int i = 1;i <= n;i++)
        {
          if(vis[i]) continue;
          int m1 = inf,u = i,sz = 0,sum = 0;
          while(!vis[u] && u != to[u])
        {
          vis[u] = 1;    
          m1 = min(a[u],m1);
          sum += a[u];
          sz++;
          u = to[u];
        }
        if(!sz) continue;
          ans += min(m1 * (sz - 1) + sum - m1,minm + m1 + minm * (sz - 1) + sum  - m1 + m1 + minm);
        }
        printf("%lld",ans);
    }
  • 相关阅读:
    CSS—BFC学习
    JS函数声明及函数表达式相关
    你想要的正则表达式笔记
    WordPress搭建自己的网站
    声纹识别
    WordPress搭建自己的网站
    L--jsp和servlet
    L--网页跳转
    L1--指针
    L--Java关键字final、static
  • 原文地址:https://www.cnblogs.com/LM-LBG/p/10617316.html
Copyright © 2011-2022 走看看