CodeForces - 351B 题解

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);
}


猜你喜欢

转载自blog.csdn.net/weixin_40844130/article/details/79793971