题目大意:10*10的地图,不过可以直接看成1*100的,从1出发,要到达100,每次走的步数用一个大小为6的骰子决定。地图上有很多个通道 A可以直接到B,不过A和B大小不确定 而且 如果99扔到100 那么只有1能走 扔其他的都要再扔一次 问从1走到100的扔骰子个数的期望
个人觉得,这道题期望没有可以加减的性质,(n不一定是从n-1过来的),所以不能采用这道题通过累加的递推。而每种状态如果写成式子,会发现$dp[100]$是已知的,而其他所有值都是未知的,所以可以通过高斯消元解出。
#include<bits/stdc++.h> #define rep(i,a,b) for(int i=a;i<=b;i++) #define dep(i,b,a) for(int i=b;i>=a;i--) #define clr(a,b) memset(a,b,sizeof(a)) #define pb push_back #define pii pair<int,int > using namespace std; typedef long long ll; ll rd() { ll x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } const int maxn=110; const int inf=0x3f3f3f3f; int T,n; double a[maxn][maxn],x[maxn]; int f[maxn]; const double eps=1e-9; int equ=100,var=100;//固定 100个方程 100个解 int Gauss()//高斯消元 返回 0 无解 返回 1有解 { int i,j,k,col,max_r; for(k=0,col=0;k<equ&&col<var;k++,col++) { max_r=k; for(i=k+1;i<equ;i++) if(fabs(a[max_r][col])>fabs(a[max_r][col])) max_r=i; if(fabs(a[max_r][col])<eps) return 0; if(k!=max_r) { for(j=col;j<var;j++) swap(a[k][j],a[max_r][j]); swap(x[k],x[max_r]); } x[k]/=a[k][col]; for(j=col+1;j<var;j++) a[k][j]/=a[k][col]; a[k][col]=1; for(i=0;i<equ;i++) { if(i!=k) { x[i]-=x[k]*a[i][col]; for(j=col+1;j<var;j++) a[i][j]-=a[k][j]*a[i][col]; a[i][col]=0; } } } return 1; } int main(){ cin>>T; int cat=1; while(T--){ cin>>n; clr(a,0),clr(x,0),clr(f,0); rep(i,1,n){ int u,v; scanf("%d%d",&u,&v); f[u]=1; a[u-1][u-1]=1; a[u-1][v-1]=-1; x[u-1]=0; } rep(i,1,99){ if(f[i])continue; if(i<=94){ x[i-1]=1; a[i-1][i-1]=1; rep(j,1,6){ a[i-1][i-1+j]=-1.0/6; } }else{ x[i-1]=1; for(int j=1;j+i<=100;j++){ a[i-1][i-1+j]=-1.0/6; } a[i-1][i-1]=1.0-(i-94)/6.0; } } a[99][99]=1,x[99]=0; Gauss(); printf("Case %d: %.8f ",cat++,x[0]); } }