【题目链接】点击打开链接

【题意】

Jeff和Furik玩游戏。对于一个长为n的序列,为1-n的排列,两个人交替操作。Jeff先手,他会选择一对相邻的数交换。

Furik会先投硬币,如果是正面,他会随机选取一对相邻的数i,i+1,且Pi > Pi+1,进行交换。如果没有可以操作的数对,他会重新投掷硬币。

如果是反面,他会随机选取一对相邻的数i,i+1,且Pi < Pi+1,进行交换。

硬币正反面的概率相等,都为50%。


当序列变为严格递增的时候,游戏结束。

问游戏结束的最小期望操作次数是多少。

【解题方法】

题解来源, Wananfly每日一题。我们知道,一个序列中, a[i] > a[j]这样的数对称为逆序数对,而题目的意思其实就是求把数列中的逆序对的数量变成0时所要的最小步数,于是可以这么做,求出逆序对的数量,然后算出递推公式,找规律,算到最后发现是两个等差数列。。。以下是递推过程:
假设d[i]为当逆序对为i对时所需要的步数,那么d[0]=0,d[1]=1,这是已知的,当i>=2,d[i]=0.5*d[i-1-1]+0.5*d[i-1+1]+1+1,化简得d[i]=d[i-2]+4;
即,d[0]=0,d[2]=4,d[4]=8,d[6]=12;
        d[1]=1,d[3]=5,d[5]=9,d[7]=13;
所以,当i为偶数时,d[i]=i*2;
            当i为奇数时,d[i]=i/2*4+1;


【代码】


//
//Created by BLUEBUFF 2016/1/9
//Copyright (c) 2016 BLUEBUFF.All Rights Reserved
//

#pragma comment(linker,"/STACK:102400000,102400000")
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/hash_policy.hpp>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <cmath>
#include <cstdio>
#include <time.h>
#include <cstdlib>
#include <cstring>
#include <sstream> //isstringstream
#include <iostream>
#include <algorithm>
using namespace std;
//using namespace __gnu_pbds;
typedef long long LL;
typedef pair<int, LL> pp;
#define REP1(i, a, b) for(int i = a; i < b; i++)
#define REP2(i, a, b) for(int i = a; i <= b; i++)
#define REP3(i, a, b) for(int i = a; i >= b; i--)
#define CLR(a, b)     memset(a, b, sizeof(a))
#define MP(x, y)      make_pair(x,y)
const int maxn = 12;
const int maxm = 2e5;
const int maxs = 10;
const int maxp = 1e3 + 10;
const int INF  = 1e9;
const int UNF  = -1e9;
const int mod  = 1e9 + 7;
//int gcd(int x, int y) {return y == 0 ? x : gcd(y, x % y);}
//typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update>order_set;
//head
int a[3010];
int main()
{
    int n;
    while(scanf("%d", &n) != EOF)
    {
        int cnt = 0;
        REP2(i, 1, n) scanf("%d", &a[i]);
        REP2(i, 1, n){
            REP2(j, i + 1, n){
                if(a[i] > a[j]) cnt++;
            }
        }
        if(cnt % 2 == 0){
            printf("%d\n", cnt * 2);
        }
        else{
            printf("%d\n", cnt / 2 * 4 + 1);
        }
    }
    return 0;
}