题意:有一个坐标轴,从s点开始,为了到达e点,走的时候是周而复始循环的,比如 0 1 2 3 3 2 0.。。,从一个点开始,每走k步都有pk的概率停下,问正好停在目标点的期望是多少;
思路:设dp[i]是在i点到e点的期望,dp[i]=p1*dp[i+1]+p2*dp[i+2]....+pk*dp[i+k](因为期望都是倒着推)
gauss 求解就可以了
因为有不能到的点,如果不能到的点算进去可能会使式子无解,所以不能倒得点不需要跟任何点关联,给他一个初始值就好
这样需要先BFS判不能到的点。
#include<bits/stdc++.h>
using namespace std;
const int N=200;
double p[N], eps=1e-10, sp;
int n, m, Y, X, D;
bool vis[N];
/****************************///高斯消元模板
int equ, var, a[N][N], x[N];
int Gauss(){
int i, j, k, col, max_r;
for(int k=0, col=0; k<equ&&col<var; k++, col++){
max_r=k;
for(i=k+1; i<equ; i++)
if(fabs(a[i][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<n; 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;
}
/******************************************/
void gouzao(){
memset(a, 0, sizeof a);
memset(x, 0, sizeof x);
for(int i=0; i<n; i++){
a[i][i]=1;
if(!vis[i]) continue;
if(i==Y || i==(n-Y)%n){
x[i]=0; continue;
}
for(int j=1; j<=m; j++){
a[i][(i+j)%n]-=p[j];
x[i]+=j*p[j];
}
}
}
/**************************************************/
bool BFS(){
queue<int> q;
q.push(X);
vis[X]=1;
while(!q.empty()){
int it=q.front(); q.pop();
for(int i=1; i<=m; i++){
if(p[i]<eps) continue;
int to=(it+i)%n;
if(!vis[to]){
vis[to]=true; q.push(to);
}
}
}
if(vis[Y]||vis[n-Y])
return true;
else
return false;
}
int main(){
int T;
scanf("%d", &T);
while(T--){
sp=0;
memset(vis, false, sizeof vis);
scanf("%d%d%d%d%d", &n, &m, &Y, &X, &D);
int tmp;
for(int i=1; i<=m; i++){
scanf("%d", &tmp);
p[i]=1.*tmp/100;
sp+=i*p[i];
}
if(Y==X){
printf("0.00\n");
continue;
}
n=(n-1)<<1;
if(D==1) X=n-X;
equ=var=n;
if(!BFS()){
printf("Impossible !\n");
continue;
}
gouzao();
if(Gauss())
printf("%.2f\n", x[X]);
else
printf("Impossible !\n");
}
return 0;
}
模板二:
double a[N][N], x[N];
bool free_x[N];
int sgn(double x){
return (x>eps)-(x-eps);
}
int gauss(){
int i, j, k, max_r, col;
double tmp;
int free_x_num, free_index;
int equ=n, var=n;
col=0;
memset(free_x, true, sizeof free_x);
for(k=0; k<equ && col<var; k++, col++){
max_r=k;
for(i=k+1; i<equ; i++){
if(sgn(fabs(a[i][col])-fabs(a[max_r][col]))>0) max_r=i;
}
if(max_r!=k){
for(j=k; j<var+1; j++) swap(a[k][j], a[max_r][j]);
}
if(sgn[a[k][col])==0){
k--; continue;
}
for(i=k+1; i<equ; i++){
if(sgn(a[i][col])!=0){
double t=a[i][col]/a[k][col];
for(j=col; j<var+1; j++){
a[i][j]=a[i][j]-a[i][j]*t;
}
}
}
}
for(i=k; i<equ; i++){
if(sgn(a[i][col])!=0) return 0;
}
if(k<var){
for(i=k-1; i>=0; i--){
free_x_num=0;
for(j=0; j<var; j++){
if(sgn[a[i][j]]!=0 && free_x[j]){
free_x_num++, free_index=j;
}
}
if(free_x_num>1) continue;
tmp=a[i][var];
for(j=0; j<var; j++){
if(sgn[a[i][j]]!=0 && j!=free_index) tmp-=a[i][j]*x[j];
}
x[free_index]=tmp/a[i][free_index];
free_x[free_index]=0;
}
return var-k;
}
for(i=var-1; i>=0; i--){
tmp=a[i][var];
for(j=i+1; j<var; j++){
if(sgn(a[i][j])!=0) tmp-=a[i][j]*x[j];
}
x[i]=tmp/a[i][i];
}
return 1;
}