BZOJ 3270 && BZOJ 1778 (期望DP && 高斯消元)
BZOJ 3270 :设置状态为Id(x,y)表示一人在x,一人在y这个状态的概率。 所以总共有n^2种状态。
p[i]表示留在该点的概率,Out[i]=(1-p[i])/Degree[i]表示离开该点的概率.
那么对于每一种状态a,b 则有P(a,b)=p[a]∗p[b]∗P(a,b)+Out[u]∗p[b]∗P(u,b)+p[a]∗Out[v]∗P(a,v)+Out[u]∗Out[v]∗P(u,v) 则有n^2个方程
对于起始状态a,b,则有P(a,b)=p[a]∗p[b]∗P(a,b)+Out[u]∗p[b]∗P(u,b)+p[a]∗Out[v]∗P(a,v)+Out[u]∗Out[v]∗P(u,v)+1
- #include <cstdio>
- #include <cstring>
- const int Maxn=;
- double p[Maxn],Out[Maxn],a[][];
- int Degree[Maxn],n,m,head[Maxn],cnt,s,t,u,v;
- struct Edge{int to,next;}edge[Maxn<<];
- inline void Add(int u,int v)
- {edge[cnt].to=v;edge[cnt].next=head[u];head[u]=cnt++;}
- inline int Id(int x,int y) {return (x-)*n+y;}
- inline void Swap(double &x,double &y) {double t=x;x=y;y=t;}
- void Build(int x,int y)
- {
- int S=Id(x,y);
- a[S][S]-=;
- for (int i=head[x];i!=-;i=edge[i].next)
- for (int j=head[y];j!=-;j=edge[j].next)
- {
- int u=edge[i].to,v=edge[j].to,T=Id(u,v);
- if (u!=v)
- {
- if (u==x && v==y) a[S][T]+=p[u]*p[v];
- else if (u==x) a[S][T]+=p[u]*Out[v];
- else if (v==y) a[S][T]+=Out[u]*p[v];
- else a[S][T]+=Out[u]*Out[v];
- }
- }
- }
- inline void Guass(int n)
- {
- for (int i=;i<=n;i++)
- {
- for (int j=i;j<=n;j++)
- if (a[j][i])
- {
- for (int k=;k<=n+;k++) Swap(a[i][k],a[j][k]);
- for (int k=;k<=n+;k++) if (k!=i) a[i][k]/=a[i][i];
- a[i][i]=;
- break;
- }
- if (!a[i][i]) continue;
- for (int j=;j<=n;j++)
- {
- if (j==i) continue;
- double t=a[j][i];
- for (int k=;k<=n+;k++) a[j][k]-=t*a[i][k];
- }
- }
- }
- int main()
- {
- scanf("%d%d%d%d",&n,&m,&s,&t);
- memset(head,-,sizeof(head));
- for (int i=;i<=m;i++)
- {
- scanf("%d%d",&u,&v);
- Add(u,v),Add(v,u);
- Degree[u]++,Degree[v]++;
- }
- for (int i=;i<=n;i++) scanf("%lf",&p[i]);
- for (int i=;i<=n;i++) Out[i]=(-p[i])/Degree[i];
- for (int i=;i<=n;i++) Add(i,i);
- for (int i=;i<=n;i++)
- for (int j=;j<=n;j++) Build(i,j);
- a[Id(s,t)][n*n+]=-;
- Guass(n*n);
- for (int i=;i<=n;i++) printf("%.6lf ",a[Id(i,i)][n*n+]);
- return ;
- }
C++
BZOJ 1778:和上面的题目差不多但是要注意的是自己不可能转移到自己因为要么炸要么移动
P(u)=Out(v)*P(v) 特别的 P(1)=Out(v)*P(v)+P/Q然后高斯消元即可.
- #include <cstdio>
- #include <cmath>
- #include <cstring>
- #define LD long double
- const int Maxn=;
- const int Maxm=;
- const LD eps=1e-;
- int Degree[Maxn],head[Maxn],n,m,P,Q,cnt,u,v;
- LD a[Maxn][Maxn],t,Out[Maxn];
- struct Edge{int to,next;}edge[Maxm<<];
- inline void Swap(LD &x,LD &y) {LD t=x;x=y;y=t;}
- inline int dcmp(LD x) {if (fabs(x)<eps) return ; return (x>)?:-;}
- inline void Add(int u,int v)
- {edge[cnt].to=v;edge[cnt].next=head[u];head[u]=cnt++;}
- inline void Build(int u)
- {
- a[u][u]=1.0;
- for (int i=head[u];i!=-;i=edge[i].next)
- a[u][edge[i].to]=-Out[edge[i].to];
- }
- inline void Gauss()
- {
- for (int i=;i<=n;i++)
- {
- for (int j=i;j<=n;j++)
- if (dcmp(a[i][j])!=)
- {
- for (int k=;k<=n+;k++) Swap(a[i][k],a[j][k]);
- for (int k=;k<=n+;k++) if (k!=i) a[i][k]/=a[i][i];
- a[i][i]=;
- break;
- }
- if (dcmp(a[i][i])==) continue;
- for (int j=;j<=n;j++)
- {
- if (j==i) continue;
- LD t=a[j][i];
- for (int k=;k<=n+;k++) a[j][k]-=t*a[i][k];
- }
- }
- }
- int main()
- {
- scanf("%d%d%d%d",&n,&m,&P,&Q); t=(LD)P/(LD)Q; t=1.0-t;
- memset(head,-,sizeof(head)); cnt=;
- for (int i=;i<=m;i++)
- {
- scanf("%d%d",&u,&v);
- Add(u,v),Add(v,u),Degree[u]++,Degree[v]++;
- }
- for (int i=;i<=n;i++) Out[i]=t/(LD)Degree[i];
- for (int i=;i<=n;i++) Build(i);
- a[][n+]=-t;
- Gauss();
- for (int i=;i<=n;i++) printf("%.9Lf\n",a[i][n+]);
- return ;
- }
C++
BZOJ 3270 && BZOJ 1778 (期望DP && 高斯消元)的更多相关文章
- BZOJ 3150 [Ctsc2013]猴子 ——期望DP 高斯消元
一堆牌的期望等于每张牌的期望值和. 考虑三个人的游戏即可得到. 然后每张牌遇到另外一张的概率相同,然后就可以列方程求解了. #include <cmath> #include <cs ...
- BZOJ_3143_[Hnoi2013]游走_期望DP+高斯消元
BZOJ_3143_[Hnoi2013]游走_期望DP+高斯消元 题意: 一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机 ...
- BZOJ 4820 [Sdoi2017]硬币游戏 ——期望DP 高斯消元
做法太神了,理解不了. 自己想到的是建出AC自动机然后建出矩阵然后求逆计算,感觉可以过$40%$ 用一个状态$N$表示任意一个位置没有匹配成功的概率和. 每种匹配不成功的情况都是等价的. 然后我们强制 ...
- HDU 2262 Where is the canteen 期望dp+高斯消元
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2262 Where is the canteen Time Limit: 10000/5000 MS ...
- hdu4418 Time travel 【期望dp + 高斯消元】
题目链接 BZOJ4418 题解 题意:从一个序列上某一点开始沿一个方向走,走到头返回,每次走的步长各有概率,问走到一点的期望步数,或者无解 我们先将序列倍长形成循环序列,\(n = (N - 1) ...
- 【noi2019集训题1】 脑部进食 期望dp+高斯消元
题目大意:有n个点,m条有向边,每条边上有一个小写字母. 有一个人从1号点开始在这个图上随机游走,游走过程中他会按顺序记录下走过的边上的字符. 如果在某个时刻,他记录下的字符串中,存在一个子序列和S2 ...
- LightOJ 1151 Snakes and Ladders 期望dp+高斯消元
题目传送门 题目大意:10*10的地图,不过可以直接看成1*100的,从1出发,要到达100,每次走的步数用一个大小为6的骰子决定.地图上有很多个通道 A可以直接到B,不过A和B大小不确定 而且 ...
- P4457-[BJOI2018]治疗之雨【期望dp,高斯消元】
正题 题目链接:https://www.luogu.com.cn/problem/P4457 题目大意 开始一个人最大生命值为\(n\),剩余\(hp\)点生命,然后每个时刻如果生命值没有满那么有\( ...
- ZJUT 1423 地下迷宫(期望DP&高斯消元)
地下迷宫 Time Limit:1000MS Memory Limit:32768K Description: 由于山体滑坡,DK被困在了地下蜘蛛王国迷宫.为了抢在DH之前来到TFT,DK必须尽快走 ...
随机推荐
- C++笔记(1)explicit构造函数
按照默认规定,只有一个参数的构造函数也定义了一个隐式转换,将该构造函数对应数据类型的数据转换为该类对象,如下面所示: class String { String ( const char* p ); ...
- TextMate 通用快捷键
原来一直在Windows上使用notepad++文本编辑器,现在换了MAC,发现notepad++ 官方没有MAC版本的,在MAC上使用也有办法,只不过实在是太麻烦了. 通过查看网友的建议,发现了Te ...
- ThinkPHP 3.2.3(二)配置
一.配置格式 1.PHP数组定义 默认所有配置文件的定义格式均采用返回PHP数组的方式,配置参数不区分大小写. 如果使用二维数组来配置更多的信息,则二级参数配置区分大小写.格式为: //项目配置文件r ...
- TranslateAnimation 运行动画后实际位置不正确问题
最近在调试android 动画时候发现一个很奇怪问题,网上搜索都说TranslateAnimation 动画运行后,实际位置要在动画结束的监听里面重新设置才会正确,不然物体位置还是在原位. 我根据网上 ...
- Oracle通过一个Value值查询数据库
---恢复内容开始--- 大家在想看看数据库中有哪些数据表中,哪些字段中有“helloworld” 这个字符串,现在数据库所有的表,视图都不能直接提供,所有必须通过循环去访问所有的数据表,所有的字段列 ...
- mysql 存储 emoji报错( Incorrect string value: '\xF0\x9F\x98\x84\xF0\x9F)的解决方案
1.报错原因: mysql utf-8 编码储存的是 2-3个的字节,而emoji则是4个字节. 2.解决办法: 修改mysql的配置文件,windows下的为my.ini(linux下的为my.cn ...
- PHP 文件包含总结 include require 命名空间 autoload spl_autoload_register 读取文件路径
总结: 1. include或require包含其他文件 使用./或者 ../,这里的当前路径和上一层路径,取决于运行脚本的路径,会存在如下问题. 在写PHP程序时,经常要用到include或requ ...
- Node.js的cluster模块——Web后端多进程服务
众所周知,Node.js是单线程的,一个单独的Node.js进程无法充分利用多核.Node.js从v0.6.0开始,新增cluster模块,让Node.js开发Web服务时,很方便的做到充分利用多核机 ...
- 14073102(CCDIKRecoil)
[目标] CCDIKRecoil [思路] 1 CCDIK和Recoil的结合 2 Recoil的回弹机制,逐渐回到原来位置 3 添加一个Recoil基类 [步骤] 1 将\Src\GameFrame ...
- VS2003"无法启动调试 没有正确安装调试器"的解决办法
VS2003"无法启动调试 没有正确安装调试器"的解决方法 在用VS2003做项目的时候,经常调试程序,但是有时候回出现如下问题“无法启动调试,没有正确安装调试器,请运行安装程序或 ...