題面
題意
給出n個數,有m次操作,每次操作給出兩個數,會有50%的概率交換這兩個數,問m次操作後逆序對的期望數量。
做法
我覺得這題的難點主要在於dp狀態的設計。
可以記表示第i個位置上的數比第j個位置上的數大的概率。
這樣開始
之後當交換p,q上的數後,
而,
最後直接根據定義統計逆序對數量即可
代碼
#include<bits/stdc++.h>
#define db double
#define N 1010
using namespace std;
int n,m,num[N];
db dp[N][N],ans;
int main()
{
int i,j,p,q;
cin>>n>>m;
for(i=1;i<=n;i++) scanf("%d",&num[i]);
for(i=1;i<=n;i++) for(j=1;j<=n;j++) dp[i][j]=(num[i]>num[j]);
for(i=1;i<=m;i++)
{
scanf("%d%d",&p,&q);
for(j=1;j<=n;j++)
{
dp[j][p]=dp[j][q]=(dp[j][p]+dp[j][q])*0.5;
dp[p][j]=dp[q][j]=1.0-dp[j][p];
}
dp[p][q]=dp[q][p]=0.5;
}
for(i=1;i<=n;i++)
{
for(j=i+1;j<=n;j++)
{
ans+=dp[i][j];
}
}
printf("%.8f",ans);
}