zoukankan      html  css  js  c++  java
  • CF351B Jeff and Furik

    Description 

    给一个1~n的排列p[i],Jeff先手可以交换任意两个相邻元素,而Furik会有0.5的几率把任意满足p[i] < p[i+1]的p[i]和p[i+1]交换,有0.5的几率把任意满足p[i] > p[i+1]的p[i]和p[i+1]交换,问将整个序列变成升序所需的最小期望步数 

    Input

    第一行一整数n表示序列长度,之后一个1~n的排列p[i] (1<=n<=3000) 

    Output 

    输出把整个序列变成升序所需的最小期望步数 

    Sample Input 

    5
    3 5 2 4 1

    Sample Output 

    13.000000 

    Solution

    考虑E[i](i为逆序对个数)的最小期望步数,则E[0]=0,E[1]=1;那么每一次Jeff肯定是交换使逆序对减少一个而Furik则有50%减少一个50%增加一个,故E[i]=1/2*(E[i-2]+1)+1/2*(E[i-1+1]+1);化简得E[i]=E[i-2]+4;

    故模拟归并排序求一次逆序对个数便可实现。

    Code

     1 #include<bits/stdc++.h>
     2 #define maxn 3005
     3 using namespace std;
     4 int n,a[maxn],t[maxn];
     5 int msort(int l,int r){
     6     if(l==r) return 0;
     7     
     8     int m=l+r>>1;
     9     int t1=msort(l,m);
    10     int t2=msort(m+1,r);
    11     
    12     int t3=0;
    13     int i=l,j=m+1,k=l;
    14     while(i<=m&&j<=r){
    15         if(a[i]>a[j]){
    16             t3+=m-i+1;
    17             t[k++]=a[j++];
    18         }
    19         else{
    20             t[k++]=a[i++];//本来就应该小于 
    21         }
    22     }
    23     while(i<=m) t[k++]=a[i++];
    24     while(j<=r) t[k++]=a[j++];
    25     
    26     for(int p=l;p<=r;p++) a[p]=t[p];//调整
    27     return t1+t2+t3; 
    28 }
    29 void init(){
    30     scanf("%d",&n);
    31     for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    32     int nd=msort(1,n);
    33     if(nd&1){
    34         printf("%lf",(double)(2*nd-1));
    35     }
    36     else printf("%lf",(double)2*nd);
    37 }
    38 int main(){
    39     init();
    40     
    41     return 0;
    42 } 
  • 相关阅读:
    《我们不一样》β冲刺_1
    《我们不一样》Alpha冲刺_1-5
    《我们不一样》团队项目软件设计方案
    如何绘制符合规范的流程图?
    《我们不一样》团队项目软件系统设计改进
    <Dare To Dream>团队项目用户验收评审
    Beta冲刺 第四天
    Beta冲刺 第三天
    Beta冲刺 第二天
    Beta冲刺 第一天
  • 原文地址:https://www.cnblogs.com/degage/p/9681704.html
Copyright © 2011-2022 走看看