codeforces258D Little Elephant and Broken Sorting

題面

題意

給出n個數,有m次操作,每次操作給出兩個數,會有50%的概率交換這兩個數,問m次操作後逆序對的期望數量。

做法

我覺得這題的難點主要在於dp狀態的設計。
可以記dp[i][j]dp[i][j]表示第i個位置上的數比第j個位置上的數大的概率。
這樣開始dp[i][j]=(num[i]>num[j])dp[i][j]=(num[i]>num[j])
之後當交換p,q上的數後,dp[i][p]=dp[i][q]=(dp[i][p]+dp[i][q])/2dp[i][p]=dp[i][q]=(dp[i][p]+dp[i][q])/2
dp[p][i]=dp[q][i]=1dp[p][i]dp[p][i]=dp[q][i]=1-dp[p][i]dp[p][q]=dp[q][p]=0.5dp[p][q]=dp[q][p]=0.5
最後直接根據定義統計逆序對數量即可i<jdp[i][j]\sum_{i<j}dp[i][j]

代碼

#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);
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章