• HDU


    题目链接

    题意:

    给定一个长度为 $n$ 的序列,现在这个序列可以不断地将第一个数放到最后,求过程中最小的逆序对。

    思路:

    一开始直接硬模拟了一发,结果是显然的。(自闭选手)

    可以一开始直接求得原始序列的逆序数,然后考虑每一位往后移的过程中对答案的贡献, 然后取最小值即可。

    当第一位的数字移动到最后一位的时候,那么比 $a[1]$ 小的数字的逆序就没有了,而增加了比 $a[1]$ 大的数字的逆序

    即每一位数字对答案的贡献为  $n-a[i] - (a[i] - 1)$;

     1 /*
     2 *  Author: windystreet
     3 *  Date  : 2018-08-10 14:36:11
     4 *  Motto : Think twice, code once.
     5 */
     6 #include<bits/stdc++.h>
     7 
     8 using namespace std;
     9 
    10 #define X first
    11 #define Y second
    12 #define eps  1e-5
    13 #define gcd __gcd
    14 #define pb push_back
    15 #define PI acos(-1.0)
    16 #define lowbit(x) (x)&(-x)
    17 #define bug printf("!!!!!
    ");
    18 #define mem(x,y) memset(x,y,sizeof(x))
    19 
    20 typedef long long LL;
    21 typedef long double LD;
    22 typedef pair<int,int> pii;
    23 typedef unsigned long long uLL;
    24 
    25 const int maxn = 5e3+7;
    26 const int INF  = 1<<30;
    27 const int mod  = 1e9+7;
    28 
    29 int tree[maxn];
    30 int n;
    31 void init(){
    32     for(int i=0;i<=n;i++)
    33         tree[i]=0;
    34     return;
    35 }
    36 void add(int x,int v){
    37     for(int i=x;i<=n;i+=lowbit(i))
    38         tree[i] += v;
    39     return ;
    40 }
    41 int query(int x){
    42     int res = 0;
    43     for(int i=x;i;i-=lowbit(i))
    44         res += tree[i];
    45     return res;
    46 }
    47 
    48 int s[maxn];
    49 
    50 void solve(){
    51     int ans ;
    52     while(scanf("%d",&n)!=EOF){
    53         init();
    54         for(int i=1;i<=n;i++){
    55             scanf("%d",&s[i]);
    56             ++s[i];
    57         }
    58         int sum = 0;
    59         for(int i=1;i<=n;i++){                    //  计算原始序列的逆序数
    60             add(s[i],1);
    61             sum += i - query(s[i]);
    62         }
    63         ans = sum;
    64         for(int i=1;i<=n;i++){
    65             sum += n - s[i] - (s[i] - 1);        // 对于每一位的贡献更新答案
    66             ans = min(ans,sum);                  // 取最优解
    67         }
    68         printf("%d
    ",ans);
    69 
    70     }   
    71     return;
    72 }
    73 
    74 int main()
    75 {
    76 //    freopen("in.txt","r",stdin);
    77 //    freopen("out.txt","w",stdout);
    78 //    ios::sync_with_stdio(false);
    79     int t = 1;
    80     //scanf("%d",&t);
    81     while(t--){
    82     //    printf("Case %d: ",cas++);
    83         solve();
    84     }
    85     return 0;
    86 }
  • 相关阅读:
    代码那些事儿之葫芦娃救爷爷
    《数学计算出题系统》功能规格说明书
    有点难
    肝不动了
    so easy, too happy
    新学期的展望
    Android Gradle插件
    重学数据结构和算法(三)之递归、二分、字符串匹配
    重学数据结构和算法(二)之二叉树、红黑树、递归树、堆排序
    重学数据结构和算法(一)之复杂度、数组、链表、栈、队列、图
  • 原文地址:https://www.cnblogs.com/windystreet/p/9455677.html
Copyright © 2020-2023  润新知