比较显然
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; int T,n,K,vis[305],a[305],b[305]; double C[305][305],F[305][305]; int main(){ scanf("%d",&T); C[0][0]=1; for (int i=1; i<=300; i++){ C[i][0]=1; for (int j=1; j<=i; j++) C[i][j]=C[i-1][j-1]+C[i-1][j]; } while (T--){ scanf("%d%d",&n,&K); for (int i=1; i<=n; i++) scanf("%d",&a[i]); memset(vis,0,sizeof(vis)); int cnt=0; for (int i=1; i<=n; i++){ int x=i,sz=0; while (!vis[x]){ vis[x]=1; sz++; x=a[x]; } if (sz) b[++cnt]=sz; } memset(F,0,sizeof(F)); F[0][0]=1; for (int i=1; i<=cnt; i++) for (int j=1; j<=K; j++) for (int k=1; k<=b[i]; k++) F[i][j]+=F[i-1][j-k]*C[b[i]][k]; F[cnt][K]/=C[n][K]; printf("%.9lf ",F[cnt][K]); } return 0; }