把两种状态化成2*n-2的一条线上的一种状态即可。很容易想到。

高斯列主元法,不知为什么WA。要上课了,不玩了。。。逃了一次课呢。。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <queue>
using namespace std;
double const eps=1e-8;
double G[210][210]; int n,m,s,e,d; double sum;
double pk[110];
double ans[210];
bool vis[210];
bool find(int i){
int k=i;
for(int j=i+1;j<n;j++){
if(fabs(G[j][i])>fabs(G[k][i]))
k=j;
}
if(fabs(G[k][i])<eps) return false;
for(int p=i;p<=n;p++)
swap(G[i][p],G[k][p]);
return true;
} bool Guass(){
for(int i=0;i<n;i++){
if(find(i)){
for(int j=i+1;j<n;j++){
double k=G[j][i]/G[i][i];
for(int p=i;p<=n;p++)
G[j][p]=G[j][p]-k*G[i][p];
}
}
else return false;
} ans[n-1]=G[n-1][n]/G[n-1][n-1];
for(int i=n-2;i>=0;i--){
double sum=0;
for(int j=n-1;j>i;j--){
sum+=(G[i][j]*ans[j]);
}
ans[i]=(G[i][n]-sum)/G[i][i];
}
return true;
} bool BFS(int s){
queue<int>q;
q.push(s);
memset(vis,false,sizeof(vis));
vis[s]=true;
while(!q.empty()){
int te=q.front();
q.pop();
for(int i=1;i<=m;i++){
if(pk[i]<eps)
continue;
int u=(te+i)%n;
if(!vis[u]){
vis[u]=true;
q.push(u);
if(u==e||u==n-e) return true;
}
}
}
return false;
} int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%d%d%d%d%d",&n,&m,&e,&s,&d);
sum=0;
n=2*n-2;
for(int i=1;i<=m;i++){
scanf("%lf",&pk[i]);
pk[i]/=100;
sum+=(i*pk[i]);
}
if (s == e){
puts ("0.00");
continue;
}
if(d==0) s=s;
else if(d==1) s=(n-s)%n;
memset(G,0,sizeof(G));
for(int i=0;i<n;i++){
G[i][i]=-1;
if(i==e||i==n-e) continue;
for(int j=1;j<=m;j++){
if(pk[j]<eps)
G[i][(j+i)%n]=pk[j];
}
G[i][n]=-sum;
}
if(!BFS(s)){
puts("Impossible !");
continue;
}
if(!Guass()){
puts("Impossible !");
}
else{
printf("%.2f\n",ans[s]);
}
}
return 0;
}

  

  这个是别人的

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <queue>
#include <algorithm>
#include <math.h>
using namespace std;
#define M 205
#define eps 1e-8
int equ, var;
double a[M][M], x[M]; 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 (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;
} //has[x]表示人在x点时的变量号,因为我们只用可达状态建立方程,所以需要编号
int has[M], vis[M], k, e, n, m;
double p[M], sum; int bfs (int u)
{
memset (has, -1, sizeof(has));
memset (a, 0, sizeof(a)); //忘记初始化WA勒,以后得注意
memset (vis, 0, sizeof(vis));
int v, i, flg = 0;
queue<int> q;
q.push (u);
k = 0;
has[u] = k++;
while (!q.empty ())
{
u = q.front ();
q.pop ();
if (vis[u]) continue;
vis[u] = 1;
if (u == e || u == n-e) //终点有两个,你懂的~
{
a[has[u]][has[u]] = 1;
x[has[u]] = 0;
flg = 1;
continue;
}
//E[x] = sum ((E[x+i]+i) * p[i])
// ----> E[x] - sum(p[i]*E[x+i]) = sum(i*p[i])
a[has[u]][has[u]] = 1;
x[has[u]] = sum;
for (i = 1; i <= m; i++)
{
//非常重要!概率为0,该状态可能无法到达,如果还去访问并建立方程会导致无解
if (fabs (p[i]) < eps) continue;
v = (u + i) % n;
if (has[v] == -1) has[v] = k++;
a[has[u]][has[v]] -= p[i];
q.push (v);
}
}
return flg;
} int main()
{
int t, s, d, i;
scanf ("%d", &t);
while (t--)
{
scanf ("%d%d%d%d%d", &n, &m, &e, &s, &d);
n = 2*(n-1);
sum = 0;
for (i = 1; i <= m; i++)
{
scanf ("%lf", p+i);
p[i] = p[i] / 100;
sum += p[i] * i;
}
if (s == e)
{
puts ("0.00");
continue;
}
//一开始向左,起点要变
if (d > 0) s = (n - s) % n;
if (!bfs (s))
{
puts ("Impossible !");
continue;
}
equ = var = k; Gauss ();
printf ("%.2f\n", x[has[s]]);
}
return 0;
}

  

HDU 4418 高斯消元法求概率DP的更多相关文章

  1. hdu 4418 Time travel 概率DP

    高斯消元求期望!! 将n时间点构成2*(n-1)的环,每一点的期望值为dp[i]=dp[i+1]*p1+dp[i+2]*p2+……+dp[i+m]*pm+1. 这样就可以多个方程,利用高斯消元求解. ...

  2. HDU 4089 Activation(概率DP)(转)

    11年北京现场赛的题目.概率DP. 公式化简起来比较困难....而且就算结果做出来了,没有考虑特殊情况照样会WA到死的.... 去参加区域赛一定要考虑到各种情况.   像概率dp,公式推出来就很容易写 ...

  3. HDU 5378 树上的概率DP Leader in Tree Land

    官方题解: 可以用求概率的思想来解决这个问题.令以i号节点为根的子树为第i棵子树,设这颗子树恰好有sz[i]个点.那么第i个点是第i棵子树最大值的概率为1/sz[i],不是最大值的概率为(sz[i]- ...

  4. hdu 4625 Dice(概率DP)

    Dice Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submi ...

  5. HDU 4405 Aeroplane chess (概率DP)

    题意:你从0开始,要跳到 n 这个位置,如果当前位置是一个飞行点,那么可以跳过去,要不然就只能掷骰子,问你要掷的次数数学期望,到达或者超过n. 析:概率DP,dp[i] 表示从 i  这个位置到达 n ...

  6. HDU - 5001 Walk(概率dp+记忆化搜索)

    Walk I used to think I could be anything, but now I know that I couldn't do anything. So I started t ...

  7. HDU 4418 Time travel 期望dp+dfs+高斯消元

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4418 Time travel Time Limit: 2000/1000 MS (Java/Othe ...

  8. HDU 2955 Robberies 背包概率DP

    A - Robberies Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submi ...

  9. HDU 4035Maze(树状+概率dp,绝对经典)

    题意: 给你n个节点的树,从1节点开始走,到每个节点都有三种情况,被杀死回到1节点,找到隐藏的出口出去,沿着当前节点相邻的边走到下一个节点,给出每个节点三种情况发生的概率分别为ki,ei,1-ki-e ...

随机推荐

  1. BA--空调静压箱的作用

    空调静压箱的主要作用有两个,一个是降低噪音:一个是提高送风距离.工作原理如下:空调出风从空调风机里面出来的时候,具有很大的风速,同时由于空调风机自身的结构原因,空调的出风并不均衡,空气在风管中相互摩擦 ...

  2. mengento 数据库模型

  3. [Beginning SharePoint Designer 2010]Chapter 3 分析SharePoint页面

    本章概要: 1.SharePoint中主要页面类型 2.SharePoint如何组织页面 3.如何编辑母板页 4.SharePoint母板页中的主要内容占位符

  4. [Beginning SharePoint Designer 2010]Chapter2 编辑页面

    本章概要: 1.如何展开隐藏任务面板和ribbon标签 2.页面编辑模式 3.代码视图模式和智能提示 4.如何组合SharePoint和页面上其他元素

  5. jsp 传值jsp 数据库 乱码解决的攻略 全套

    jsp传值给jsp中文乱码 传值给数据库乱码的解决方法 所有的用到编码的所有统一utf-8 1.装mysql的时候有选择编码的界面的那个地方选utf-8编码 2 建数据库的时候选择 字符集 排序规则所 ...

  6. How to remove focus without setting focus to another control?

    How to remove focus without setting focus to another control? Ask Question up vote 67 down vote favo ...

  7. 17.UNP第一章 简介

    获取时间的客户端代码: //客户端程序 #include "unp.h" int main(int argc, char **argv) { int sockfd, n; ]; s ...

  8. DOM相关知识点

    内容待补充... DOM相关注意题目: DOM的最小组成单位叫做 //节点 Node DOM 有自己的国际标准,目前的通用版本是 //DOM 3 DOM 树的根节点 //HTML 元素 Element ...

  9. Hibernate框架学习(七)——多对多关系

    一.关系表达 1.表中的表达 2.实体中的表达 3.orm元数据中的表达 在User.hbm.xml中添加: 在Role.hbm.xml中添加(与上相反): 二.操作关联属性 1.保存员工及角色 pu ...

  10. update没带where,寻找问题的思路

    数据库版本:5.6.16 前几天,在测试环境中,不知道为什么突然之间,所有的一个字段值全部变成了12,需要将备份还原后开发重新清理垃圾数据并开始测试. 在开发提供 SQL语句的情况下,能否查到是谁做了 ...