CodeForces 352D. Jeff and Furik

题意:给n个数,第一个人选取相邻两个递降的数交换顺序,第二个人一半的概率选取相邻两个递降的数交换顺序,一半的概率选取相邻两个递增的数交换顺序。两个人轮流操作,求整个数列变成递增数列所需交换次数的期望。

题解:首先显然要求逆序对数,记为cnt。想了很多计算概率加组合数等,没算出来= =

后来看了题解找规律,当cnt是奇数时,答案是cnt*2-1,当cnt是偶数时,答案是cnt*2

(自己算一下也能算出来,但是没有完全不知道怎么证明,解法就算了,但是以后知道这种题可以直接推公式了……)

代码:

#include <cstdio>

int a[3005];

int main()
{
    //freopen("in.txt", "r", stdin);

    int n;
    scanf("%d", &n);

    for (int i = 0; i < n; ++i) scanf("%d", &a[i]);

    int cnt = 0; // 逆序对数
    for (int i = 1; i < n; ++i)
        for (int j = 0; j < i; ++j)
            if (a[i] < a[j]) ++cnt;

    if (cnt & 1) printf("%d", cnt * 2 - 1);
    else printf("%d", 2 * cnt);

    return 0;
}

  

原文地址:https://www.cnblogs.com/wenruo/p/4749933.html