zoukankan      html  css  js  c++  java
  • CodeForces 258D Little Elephant and Broken Sorting(期望)

    CF258D Little Elephant and Broken Sorting

    题意

    题意翻译

    有一个(1sim n)的排列,会进行(m)次操作,操作为交换(a,b)。每次操作都有(50\%)的概率进行。

    求进行(m)次操作以后的期望逆序对个数。

    (n,mle 1000)

    输入输出格式

    输入格式:

    The first line contains two integers (n) and (m) ((1leq n,mleq 1000,n>1)) — the permutation size and the number of moves. The second line contains (n) distinct integers, not exceeding (n) — the initial permutation. Next (m) lines each contain two integers: the (i)-th line contains integers (a_{i}) and (b_{i}) ((1leq a_{i},b_{i}leq n,a_{i} eq b_{i})) — the positions of elements that were changed during the (i)-th move.

    输出格式:

    In the only line print a single real number — the answer to the problem. The answer will be considered correct if its relative or absolute error does not exceed (10^{-6}).

    输入输出样例

    输入样例#1:

    2 1
    1 2
    1 2
    

    输出样例#1:

    0.500000000
    

    输入样例#2:

    4 3
    1 3 2 4
    1 2
    2 3
    1 4
    

    输出样例#2:

    3.000000000
    

    思路

    这道题真的水。 --Mercury

    完全想不到的状态设计,感谢(Mercury)巨佬的指点。

    定义(f(i,j))为位置(i)上的数比位置(j)上的数大的概率。假设每次交换都是(100\%)成功的,不妨设这次交换的数的下标为(a,b),那么对于任意的(f(i,a),f(i,b))就要被交换,(f(a,i),f(b,i))也要被交换。可是当前交换的概率是(50\%)的,所以(f(i,a),f(i,b))之间的差值要被分别减少(50\%),也就相当于(f(i,a)=f(i,b)=(f(i,a)+f(i,b))div 2)。同理,(f(a,i)=f(b,i)=(f(a,i)+f(b,i))div 2)。最后的逆序对期望,也就是(Sigma [i<j]f(i,j) imes 1),也就是(Sigma [i<j]f(i,j))

    还要再胡扯两句。 其实只要想出了(f(i,j))这个东西,什么都简单了,可是又会有几个人能够想到这种方法呢?完全没有类似的情况作为参考,掌握了这道题却又能给类似的题提供经验(毕竟也没有类似的题)。下一次见到了这种思维量大的题,还是不太能想得出。思维的活跃在(OI)中还是有很大的作用的啊!

    AC代码

    #include<bits/stdc++.h>
    #define RG register
    using namespace std;
    int n,m,a[1005];
    double ans,f[1005][1005];
    int read()
    {
        RG int re=0;RG char ch=getchar();
        while(!isdigit(ch)) ch=getchar();
        while(isdigit(ch)) re=(re<<3)+(re<<1)+ch-'0',ch=getchar();
        return re;
    }
    int main()
    {
        n=read(),m=read();
        for(RG int i=1;i<=n;i++) a[i]=read();
        for(RG int i=1;i<=n;i++)
            for(RG int j=i+1;j<=n;j++)
                if(a[i]>a[j]) f[i][j]=1.0;
                else f[j][i]=1.0;
        while(m--)
        {
            RG int x=read(),y=read();
            if(x==y) continue;
            for(RG int i=1;i<=n;i++)
            {
                if(i==x||i==y) continue;
                f[i][x]=f[i][y]=(f[i][x]+f[i][y])/2;
                f[x][i]=f[y][i]=(f[x][i]+f[y][i])/2;
            }
            f[x][y]=f[y][x]=0.5;
        }
        for(RG int i=1;i<=n;i++)
            for(RG int j=i+1;j<=n;j++)
                ans+=f[i][j];
        printf("%.8f",ans);
        return 0;
    }
    
  • 相关阅读:
    LeetCode 264. Ugly Number II
    LeetCode 231. Power of Two
    LeetCode 263. Ugly Number
    LeetCode 136. Single Number
    LeetCode 69. Sqrt(x)
    LeetCode 66. Plus One
    LeetCode 70. Climbing Stairs
    LeetCode 628. Maximum Product of Three Numbers
    Leetcode 13. Roman to Integer
    大二暑假周进度报告03
  • 原文地址:https://www.cnblogs.com/coder-Uranus/p/9899145.html
Copyright © 2011-2022 走看看