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