您的位置:首页 > 其它

Codeforces Round #204 (Div. 1) B. Jeff and Furik 1月7日

2017-01-09 09:39 537 查看
【题目链接】点击打开链接

【题意】

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: