给你一个地图10*10,从1到100,问掷骰子的次数的期望,中间会有传送门从a到b。
高斯消元基础题,学了一发板子,x存放多出来的,a存放系数;
要么是dp[i]=(dp[i+1]+...+dp[i+6]+6)/6;
要么是dp[i]=dp[go[i]];
值得注意的是哪怕是没有dp[i+6]也要加6,因为说了,如果超界那投得次数也要算上。
#include <iostream>
#include <functional>
#include <algorithm>
#include <complex>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iomanip>
#include <sstream>
#include <utility>
#include <bitset>
#include <cctype>
#include <cstdio>
#include <limits>
#include <memory>
#include <string>
#include <vector>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <list>
#include <map>
#include <set>
using namespace std;
#define eps 1e-9
const int MAXN=220;
double a[MAXN][MAXN],x[MAXN];
int equ,var;
int go[110];
//int back[110];
int Gauss()
{
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[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 < 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(int i = 0; i < equ; i++)
if(i != k)
{
x[i] -= x[k]*a[i][k];
for(j = col+1; j < var; j++)a[i][j] -= a[k][j]*a[i][col];
a[i][col] = 0;
}
}
return 1;
}
int main()
{
int i,j,ncas=1;
int t;
// double a[110][110];
scanf("%d",&t);
while(t--)
{
memset(a,0.0,sizeof(a));
memset(x,0.0,sizeof(x));
for (int i=0;i<100;i++) x[i]=1;
memset(go,-1,sizeof(go));
equ=var=100;
int all;
scanf ("%d",&all);
while (all--)
{
int t1,t2;
scanf ("%d%d",&t1,&t2);
t1--;
t2--;
go[t1]=t2;
}
for (int i=0; i<100; i++)
{
if (go[i]==-1)
{
if (i<=93)
{
a[i][i]=6.0;
a[i][i+1]=-1.0;
a[i][i+2]=-1.0;
a[i][i+3]=-1.0;
a[i][i+4]=-1.0;
a[i][i+5]=-1.0;
a[i][i+6]=-1.0;
x[i]=6;
}
else if (i==99)
{
a[i][i]=1.0;
x[i]=0.0;
}
else
{
a[i][i]=(99-i)*1.0;
int epx=1;
while (i+epx<=99)
{
a[i][i+epx]=-1.0;
epx++;
}
x[i]=6*1.0;
}
}
else
{
a[i][i]=1.0;
a[i][go[i]]=-1.0;
x[i]=0;
}
}
Gauss();
printf ("Case %d: %.10f\n",ncas++,x[0]);
}
return 0;
}