CodeForces 258D Little Elephant and Broken Sorting(期望)
CF258D Little Elephant and Broken Sorting
題意
題意翻譯
有一個\(1\sim n\)的排列,會進行\(m\)次操作,操作為交換\(a,b\)。每次操作都有\(50\%\)的概率進行。
求進行\(m\)次操作以後的期望逆序對個數。
\(n,m\le 1000\)
輸入輸出格式
輸入格式:
The first line contains two integers \(n\) and \(m\) \((1\leq n,m\leq 1000,n>1)\) — the permutation size and the number of moves. The second line contains \(n\)
輸出格式:
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,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;
}