#1166 : 交换代数
时间限制:20000ms
单点时限:1000ms
内存限制:256MB
-
2 0 1
样例输出 -
3.000000
#include <iostream> #include<stdio.h> #include<string.h> #include<algorithm> #include<math.h> #define eps 1e-9 using namespace std; int b[25]; int d[25]; double a[25][25]; double x[25]; int n; double Gauss() { int row, col, max_r; int equ,var; equ = var = n; row = col = 0; while(row < equ && col < var) { max_r = row; for(int i = row+1; i < equ; i++) if(fabs(a[i][col])-fabs(a[max_r][col]) > eps) max_r = i; if(max_r != row) for(int j = col; j <= var; j++) swap(a[row][j], a[max_r][j]); if(fabs(a[row][col]) < eps) { col++; continue; } for(int i = row+1; i < equ; i++) { if(fabs(a[i][col]) > eps) { double t = a[i][col]/a[row][col]; a[i][col] = 0.0; for(int j = col+1; j <= var; j++) a[i][j] -= a[row][j]*t; } } row++; col++; } for(int i = equ-1; i >= 0; i--) { if(fabs(a[i][i]) < eps) continue; double tmp = a[i][var]; for(int j = i+1; j < var; j++) tmp -= a[i][j]*x[j]; x[i] = tmp/a[i][i]; } } int main() { while(cin>>n) { for(int i=1;i<=n;i++) cin>>b[i]; b[0]=0;b[n+1]=0; int ans=0; for(int i=0;i<=n;i++) { d[i]=b[i]^b[i+1]; if(d[i]==0) ans++; } memset(d,0,sizeof(d)); memset(a,0,sizeof(a)); //dp[m]=m(m-1)/n(n-1)*dp[m-2]+(n-m)(n-m-1)/n(n-1)*dp[m+2]+2*m(n-m)/n(n-1)*dp[m]+1 n=n+1;//0-N 所以个数为n+1 for(int i=0;i<n;i++) { a[i][i]=1.0-2.0*i*(n-i)/(n*(n-1)*1.0); if(i>=2) a[i][i-2]=-(i*(i-1))/((n*(n-1))*1.0); if(i<n-2) a[i][i+2]=-(n-i)*(n-i-1)/(n*(n-1)*1.0); a[i][n]=1; } Gauss(); printf("%lf\n",x[ans]); } return 0; }
描述
少女幽香这几天正在学习交换代数,然而她什么也没有学会,非常痛苦。于是她开始玩起了一个简单的小游戏,来放松一下。
地面上一共有n个球,一开始有一些是黑色的,有一些是白色的。每次她随机选择一个区间(一共有n(n+1)/2个区间,每个区间有相等的概率被选择),把这个区间的颜色反转,即将该区间中白球变黑球,黑球变白球。
现在她想要知道期望情况下,多少次反转能够使得整个区间都是白色的。
输入
第一行n (1 <= n <= 20),表示球的数量。
接下来一行n个数,表示这些球的颜色,0表示白色,1表示黑色。
输出
一行一个实数,表示答案。你的答案与标准答案的绝对误差在10-4以内就算正确。
本文介绍了一个基于交换代数概念的小游戏。游戏中有n个球,初始状态为黑白两色混合,玩家通过随机选择区间反转颜色的方式,试图将所有球变为白色。文章提供了计算期望反转次数的算法,并附带代码实现。

1185

被折叠的 条评论
为什么被折叠?



