高斯消元 求期望
存个代码
hdu 4418
题解来源http://972169909-qq-com.iteye.com/blog/1689107
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <stack>
#include <queue>
#include <cmath>
using namespace std;
const double eps=1e-10;
const int maxn=255;
int n,m,tot,poi,X,Y;
int cod[maxn];
double a[maxn][maxn],x[maxn],p[maxn];
double sum;
char mar[20][20];
int dx[]={0,0,1,-1},dy[]={1,-1,0,0};
int gauss_cpivot(int n,int m,double a[][maxn],double b[]){
int i,j,k,row;
double maxp,t;
for (k=0;k<m;k++){
for (maxp=0,i=k;i<n;i++)
if (fabs(a[i][k])>fabs(maxp))
maxp=a[row=i][k];
if (fabs(maxp)<eps)
return 0;
if (row!=k){
for (j=k;j<m;j++)
t=a[k][j],a[k][j]=a[row][j],a[row][j]=t;
t=b[k],b[k]=b[row],b[row]=t;
}
for (j=k+1;j<m;j++){
a[k][j]/=maxp;
for (i=k+1;i<n;i++)
a[i][j]-=a[i][k]*a[k][j];
}
b[k]/=maxp;
for (i=k+1;i<n;i++)
b[i]-=b[k]*a[i][k];
}
for (i=n-1;i>=0;i--)
for (j=i+1;j<m;j++)
b[i]-=a[i][j]*b[j];
return 1;
}
bool bfs()
{
queue<int>q;
q.push(X);
memset(cod,-1,sizeof(cod));
memset(a,0,sizeof(a));
cod[X]=0;
tot=1;
bool flag;
int i;
int now;
flag=false;
while (!q.empty())
{
now=q.front(); q.pop();
// printf("poi=%d nowx=%d nowy=%d\n",poi,now.x,now.y);
a[cod[now]][cod[now]]=1;
x[cod[now]]=sum;
if (now==Y || now==n-Y)
{
flag=true;
x[cod[now]]=0;
}
else
{
for (i=1;i<=m;i++)
{
if (fabs(p[i])<eps) continue;
int nex=(now+i)%n;
if (cod[nex]==-1)
{
cod[nex]=tot++;
q.push(nex);
}
a[cod[now]][cod[nex]]-=p[i];
}
}
}
return flag;
}
int main()
{
int cases,D,i;
while (~scanf("%d",&cases))
{
while (cases--)
{
scanf("%d%d%d%d%d",&n,&m,&Y,&X,&D);
n=2+2*(n-2); sum=0.0;
for (i=1;i<=m;i++)
{
scanf("%lf",&p[i]);
p[i]*=0.01;
sum+=i*p[i];
}
if (X==Y) printf("0.00\n");
else
{
if (D) X=(n-X)%n;
if (!bfs()) printf("Impossible !\n");
else
{
gauss_cpivot(tot,tot,a,x);
// for (int i=0;i<tot;i++) printf(" %.3f",x[i]);
// printf("\n");
printf("%.2f\n",x[cod[X]]);
}
}
}
}
return 0;
}
hdu 2262
题解来源:http://blog.csdn.net/gatevin/article/details/42127647
因为没有清空a数组wa了n发
感觉好像对期望的套路有点理解了
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <stack>
#include <queue>
#include <cmath>
using namespace std;
const double eps=1e-10;
const int maxn=255;
int n,m,tot,poi;
int cod[20][20];
double a[maxn][maxn],x[maxn];
struct pt
{
int x,y;
}st;
char mar[20][20];
int dx[]={0,0,1,-1},dy[]={1,-1,0,0};
int gauss_cpivot(int n,int m,double a[][maxn],double b[]){
int i,j,k,row;
double maxp,t;
for (k=0;k<m;k++){
for (maxp=0,i=k;i<n;i++)
if (fabs(a[i][k])>fabs(maxp))
maxp=a[row=i][k];
if (fabs(maxp)<eps)
return 0;
if (row!=k){
for (j=k;j<m;j++)
t=a[k][j],a[k][j]=a[row][j],a[row][j]=t;
t=b[k],b[k]=b[row],b[row]=t;
}
for (j=k+1;j<m;j++){
a[k][j]/=maxp;
for (i=k+1;i<n;i++)
a[i][j]-=a[i][k]*a[k][j];
}
b[k]/=maxp;
for (i=k+1;i<n;i++)
b[i]-=b[k]*a[i][k];
}
for (i=n-1;i>=0;i--)
for (j=i+1;j<m;j++)
b[i]-=a[i][j]*b[j];
return 1;
}
bool bfs()
{
queue<pt>q;
q.push(st);
memset(cod,-1,sizeof(cod));
memset(a,0,sizeof(a));
cod[st.x][st.y]=0;
tot=1;
poi=0;
bool flag;
int i;
pt now;
flag=false;
while (!q.empty())
{
now=q.front(); q.pop();
// printf("poi=%d nowx=%d nowy=%d\n",poi,now.x,now.y);
a[poi][cod[now.x][now.y]]=1;
x[poi]=1;
if (mar[now.x][now.y]=='$')
{
flag=true;
x[poi]=0;
}
else
{
int fx=4;
for (i=0;i<4;i++)
{
int nx=now.x+dx[i];
int ny=now.y+dy[i];
if (nx<0 || nx>=n || ny<0 || ny>=m ||mar[nx][ny]=='#') fx--;
}
for (i=0;i<4;i++)
{
int nx=now.x+dx[i];
int ny=now.y+dy[i];
if (!(nx<0 || nx>=n || ny<0 || ny>=m ||mar[nx][ny]=='#'))
{
if (cod[nx][ny]==-1)
{
cod[nx][ny]=tot++;
pt nn;
nn.x=nx; nn.y=ny;
// printf("nx=%d ny=%d\n",nx,ny);
q.push(nn);
}
a[poi][cod[nx][ny]]=-1.0/fx;
}
}
}
poi++;
}
return flag;
}
int main()
{
while (~scanf("%d%d",&n,&m))
{
for (int i=0;i<n;i++)
{
scanf("%s",mar[i]);
for (int j=0;j<m;j++)
if (mar[i][j]=='@') {st.x=i; st.y=j;}
}
if (!bfs()) printf("-1\n");
else
{
gauss_cpivot(poi,tot,a,x);
// for (int i=0;i<tot;i++) printf(" %.3f",x[i]);
// printf("\n");
printf("%.6f\n",x[cod[st.x][st.y]]);
}
}
return 0;
}