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\n", ans*2.0);
else printf("%.6lf\n",ans * 2.0 - 1);
}