码迷,mamicode.com
首页 > 其他好文 > 详细

逆序对 inversion

时间:2019-01-27 21:50:04      阅读:192      评论:0      收藏:0      [点我收藏+]

标签:sed   lock   style   stdout   print   文件   需要   比较   http   

    评测传送门

【问题描述】
  有一个1 ? n的排列,你会依次进行m次操作,第i次操作表示为(x i , y i ),交换以这两个
  值为下标的元素,每次操作有一半的概率成功,你需要求出最后序列的逆序对的期望个数。
【输入】
  输入文件 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

gql的方法:

  把逆序对的期望数分开来算

  f[i][j] 表示编号为 i 的数大于编号为 j 的数的概率

  维护这个数组

  统计答案的时候就直接吧所有 i<j 时的 f[i][j] 相加即可

  怎么维护这个数组呢

  首先输入完n个数后 可以初始化得出最初的 f[ ][ ]

  然后边输入 xi yi 边更新 f[ ][ ]  具体见代码啦

技术分享图片
 1 #include<iostream>
 2 #include<cstdio>
 3 #define go(i,a,b) for(register int i=a;i<=b;i++)
 4 #define db double
 5 using namespace std;
 6 int read()
 7 {
 8     int x=0,y=1;char c=getchar();
 9     while(c<0||c>9) {if(c==-) y=-1;c=getchar();}
10     while(c>=0&&c<=9) {x=(x<<1)+(x<<3)+c-0;c=getchar();}
11     return x*y;
12 }
13 int n,m,x,y,a[1010];
14 db f[1010][1010],ans;
15 int main()
16 {
17     //freopen("1.in","r",stdin);
18     //freopen("1.out","w",stdout);
19     n=read();m=read();
20     go(i,1,n) a[i]=read();
21     go(i,1,n) go(j,1,n) if(a[i]>a[j]) f[i][j]=1;
22     go(i,1,m)
23     {
24         x=read();y=read();
25         go(j,1,n)
26         {
27             f[x][j]=f[y][j]=(f[x][j]+f[y][j])*0.5;
28             f[j][x]=f[j][y]=1-f[x][j];
29         }
30         f[x][y]=f[y][x]=0.5;
31     }
32     go(i,1,n) go(j,i+1,n) ans+=f[i][j];
33     printf("%.8lf",ans);
34     return 0;
35 }
View Code

    

逆序对 inversion

标签:sed   lock   style   stdout   print   文件   需要   比较   http   

原文地址:https://www.cnblogs.com/forward777/p/10327371.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!