本题目是典型的建立方程组用高斯消元法求解。
但是问题在于方程组有n个,未知数有n个,直接上模板会超时,那么手写个消元就可以了,对高斯消元每行的操作对于本题目都可以降到o(m)。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
#define rep(i,n) for(int i=0;i<(int)n;i++)
#define rep1(i,x,y) for(int i=x;i<=y;i++)
typedef long long ll;
typedef long long LL;
const int N = 50505;
double c[N][6];
double d[N][30];
int main()
{
int n,m;
while(scanf("%d %d",&n,&m)==2 && n+m){
rep1(i,1,n) rep1(j,1,m) scanf("%lf",&c[i][j]);
memset(d,0,sizeof(d));
d[n][6]=1; d[n][29]=0;
rep1(i,1,n-1){
d[i][6] = 0;
int sum =0; rep1(k,1,m) sum+=c[i][k];
d[i][29] = 1;
rep1(j,max(1,i-m),min(i+m,n))if(j!=i){
double p;
if(j<i) p=0.3*c[i][i-j]/(1+sum);
if(j>i) p=0.7*c[i][j-i]/(1+sum);
d[i][6+(j-i)]=-p; d[i][6]+=p;
}
}
rep1(i,1,n-1){
int r = i; double tem=d[i][6];
for(int j=1;i+j<=n&&j<=m;j++){
if(fabs(d[i+j][6-j]) > fabs(tem)){
tem=d[i+j][6-j]; r=i+j;
}
}
if(r!=i) {
rep1(j,6,6+m+r-i) swap(d[i][j],d[r][j-(r-i)]);
swap(d[i][29],d[r][29]);
}
for(int j=1;i+j<=n&&j<=m;j++)if(d[i+j][6-j]!=0){
double t=d[i+j][6-j]/d[i][6];
for(int k=6-j;k<=6+m;k++) d[i+j][k]-=t*d[i][k+j];
d[i+j][29]-=d[i][29]*t;
}
}
for(int i=n-1;i>=1;i--){
for(int j=min(n,i+m);j>i;j--){ d[i][29]-=d[j][29]*d[i][j-i+6]; }
d[i][29]=d[i][29]/d[i][6];
}
printf("%.2lf\n",d[1][29]);
}
return 0;
}