
2 4 2 0 1 0 50 50 4 1 0 2 1 100
8.14 2.00
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#define maxn 205
#define MAXN 100005
#define mod 1000000009
#define INF 0x3f3f3f3f
#define pi acos(-1.0)
#define eps 1e-6
typedef long long ll;
using namespace std;
int n,m,sx,ex,dir,flag,cnt,tot;
int pk[maxn],vis[maxn],mp[maxn];
double a[maxn][maxn],x[maxn];
//方程的左边的矩阵和等式右边的值,求解之后xi存的就是第i个未知数的结果 下标从0开始
int equ,var;//方程数和未知数个数
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(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;
}
void bfs()
{
int i,j,t;
queue<int>q;
memset(vis,0,sizeof(vis));
tot=0;
vis[sx]=1;
q.push(sx);
while(!q.empty())
{
int nx=q.front();
mp[nx]=tot++;
q.pop();
for(j=1;j<=m;j++)
{
if(pk[j]==0) continue ;
int pos=(nx+j)%cnt;
if(!vis[pos])
{
vis[pos]=1;
q.push(pos);
}
}
}
}
void solve()
{
int i,j,t,cxx=-1,tmp;
equ=var=tot;
memset(a,0,sizeof(a));
memset(x,0,sizeof(x));
for(i=0; i<=n+n-3; i++) // 建立方程式
{
if(!vis[i]) continue ;
cxx++;
if(i==ex||i+ex==cnt) // 终点
{
a[cxx][mp[i]]=1;
x[cxx]=0;
continue ;
}
t=0;
for(j=1;j<=m;j++)
{
int pos=(i+j)%cnt;
a[cxx][mp[pos]]+=-pk[j];
t+=pk[j]*j;
}
a[cxx][mp[i]]+=100;
x[cxx]=t;
}
Gauss();
printf("%.2f\n",x[mp[sx]]);
}
int main()
{
int i,j,t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d%d%d",&n,&m,&ex,&sx,&dir);
for(i=1; i<=m; i++)
{
scanf("%d",&pk[i]);
}
if(sx==ex) // 起点为终点特判 不然会mod 0
{
printf("0.00\n");
continue ;
}
cnt=n+n-2;
if(dir==1) sx=cnt-sx; // 由于对称性 可看做cnt-sx向右走(当然也可以不用 不过取模是要注意)
bfs(); // 给走的到的点编号
if(!vis[ex]&&!vis[cnt-ex]) // 这里要记得 虚拟节点后有两个终点 可能只能一个方向到达终点 如我写的数据
{
printf("Impossible !\n");
continue ;
}
solve();
}
return 0;
}
/*
1
8 7 1 6 0
0 0 0 0 0 0 100
*/
hdu 4418 Time travel (概率dp 细节好多),布布扣,bubuko.com
hdu 4418 Time travel (概率dp 细节好多)
原文:http://blog.csdn.net/tobewhatyouwanttobe/article/details/38017859