zoukankan      html  css  js  c++  java
  • 逆序对

    依旧还是TT的评测
    题目描述

    有一个1 − n的排列,你会依次进行m次操作,第i次操作表示为(x i , y i ),交换以这两个
    值为下标的元素,每次操作有一半的概率成功,你需要求出最后序列的逆序对的期望个数。

    tips:期望值

    输入

    输入文件 inversion.in。
    第一行两个数n, m。
    第二行n个数表示初始的排列。
    接下来m行,每行两个数表示x i , y i 。

    输出

    输出文件 inversion.out。
    一个实数表示答案,四舍五入保留到小数点后 8 位,要求绝对误差不超过 10 -6 。
    (评测时开启实数比较模式)

    样例输入

    4 3

    1 3 2 4

    1 2

    2 3

    1 4

    样例输出

    3.00000000

    数据说明

    30%: n ≤ 10, m ≤ 20
    100%: n ≤ 1000, m ≤ 1000

    思路

    1.我们用一个f[i][j]数组储存i位置上的值和j位置上的值之间是否存在逆序对

    2.然后输入我们要交换的2个位置x,y,用for循环来计算出他对每个的影响,因为每次操作有50%的成功几率,那么原来的f[x][i]和f[y][i]之间要*0.5

    f[x][i]=f[y][i]=0.5*(f[x][i]+f[y][i]);

    那么

    f[i][x]=f[i][y]=1-f[x][i];

    由于是x,y互换

    所以f[x][y]=f[y][x]=0.5;

    3.然后我们所需要做的就是把它们加起来,求出最后的期望值(期望个数)

    代码

    #include<bits/stdc++.h>
    using namespace std;
    int n,m;
    int a[1050];
    double ans=0;
    double f[1010][1010];
    int scan()//借鉴GQL的更新快读,please remember!!
    {
        int as=0;
        bool y=1;
        char c=getchar();
        while(c!='-'&&(c>'9'||c<'0')) c=getchar();
        if(c=='-') y=0,c=getchar();
        while(c>='0'&&c<='9')
            as=(as<<3)+(as<<1)+(c^'0'),c=getchar();
        return y?as:-as;
    }
    int main()
    {
        n=scan();
        m=scan();
        for(int i=1;i<=n;i++)
            a[i]=scan();
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                f[i][j]=a[i]>a[j];//f[i][j]表示i和j之间是否存在逆序对
                //    cout<<i<<" "<<j<<" "<<f[i][j]<<endl;
            }
        }
        while(m--)
        {
            int x=scan();//输入要交换的2个位置
            int y=scan();
            for(int i=1;i<=n;i++)//!!!!,x,y是2个位置
            {
                f[x][i]=f[y][i]=(double)0.5*(f[x][i]+f[y][i]);
                f[i][x]=f[i][y]=(double)1-f[x][i];
            }
            f[x][y]=f[y][x]=0.5;
        }
        ans=0;
        for(int i=1;i<=n;i++)
        {
            for(int j=i+1;j<=n;j++)
            {
                ans+=(double)f[i][j];
            }
        }
        printf("%.8lf",ans);
        return 0;
        
    }
    View Code
  • 相关阅读:
    在实体属性上通过注解格式化日期
    @Validated和@Valid区别:Spring validation验证框架对入参实体进行嵌套验证必须在相应属性(字段)加上@Valid而不是@Validated
    两种根据关键字查询的方法SQL
    excel批量导入数据
    下载excel模板
    上传人员照片
    身份证校验类
    把字符串参数分割成数组 传入SQL foreach遍历查询
    使用Hibernate-Validator优雅的校验参数
    如何使用Graphics2D在一张图片上画线(包括箭头)
  • 原文地址:https://www.cnblogs.com/KSTT/p/10327759.html
Copyright © 2011-2022 走看看