CodeForces

Jeff has become friends with Furik. Now these two are going to play one quite amusing game.

题目链接:http://codeforces.com/problemset/problem/351/B

题目大意: 

1. 一串数字P,两个人,轮流交换相邻的两个数字,使这串成为从小大到顺序的一串数字。

2. 第一个人J直接可以换相邻的两个数字,第二个人K扔硬币,正面就使得Pi > Pi + 1, 反面就 Pi < Pi + 1;  默认概率分别均为0.5。

3. 两个人都希望交换的次数最少。 所以第二个人J会换相邻的两个数字使得Pi < P i + 1, 而K则需要抛硬币。

4. 输出最少的次数。

解题思路:

1. 首先想到逆序数, 直接两层循环比较, 然后得出逆序数ans,即需要对这串数字交换多少次数。

2. 分析两个人对逆序数减少的贡献

①. J很简单考虑,他不需要抛硬币并且希望交换次数少,所以每次抛硬币会使逆序数减少1个,ans = ans - 1.

②. K则会抛硬币来决定他是使逆序数ans = ans + 1 还是 ans = ans - 1(不由他自己决定虽然他也希望交换的次数最少),两种情况各占百分之五十, 所以以平均下来K其实是什么都没有干的。

3. ans分奇偶

①. 偶数 ans * 2;

②. 奇数 (ans-1)*2 + 1;

AC代码

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
int a[10000];
int main()
{
    long long ans = 0;
    int n;
    scanf("%d", &n);
    for(int i = 0; i < n; i++) scanf("%d", &a[i]);
    for(int i = 0; i < n; i++)
        for(int j = i + 1; j < n; j++)
            if(a[i] > a[j]) ans++;  // ans为逆序数;
    if(ans % 2 == 0) printf("%.6lf
", ans*2.0);
    else printf("%.6lf
",ans * 2.0 - 1);
}
 
原文地址:https://www.cnblogs.com/smuzoey/p/11787454.html