概率DP入门学习QAQ
emmmm博客很多都烂尾了。。。但是没空写。。先写一下正在学的东西好了
概率DP这东西每次考到都不会。。听题解也是一脸懵逼。。所以决定学习一下这个东东。。毕竟NOIP考过。。。比什么平衡树实在多了QAQ
有时间再去复习一下平衡树和KMP,AC自动机什么的,都忘光了。。
概率DP这东东。。我也不好说啥定义(毕竟是蒟蒻嘛。。直接刷题咯)
T1:hdu3853
题意:一个r行c列的格子,起始点在(1,1),终点在(r,c),每一步可能的走法有:不动、向右走、向下走,每走一步花费两点魔法值,现给出在每一点三种走法的概率,求走完迷宫时所花魔法值的期望。
这道题目可以看出是概率DP吧、、、那么我们显然知道一个事实dp[r][c]=0,不难写出DP方程:dp[i][j] = p[i][j][1]*dp[i][j] + p[i][j][2]*dp[i][j+1] + p[i][j][3]*dp[i+1][j] + 2
但是接下来的化简我理解了很久。。。之后我才明白QAQ
下面贴出化简的关键步骤
因为dp[i][j]-p[i][j][1]*dp[i][j]=dp[i][j]*(1-p[i][j][1])
所以dp[i][j] = (p[i][j][2]*dp[i][j+1] + p[i][j][3]*dp[i+1][j] + 2)/(1-p[i][j][1])
下面贴上代码:
#include<cstdio>
using namespace std;
double dp[][];
double p[][][];
int n,m;
int main(){
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)scanf("%lf%lf%lf",&p[i][j][],&p[i][j][],&p[i][j][]);
for(int i=n;i>=;i--)
for(int j=m;j>=;j--){
if(p[i][j][]==||(i==n&&j==m))continue;
dp[i][j]=(p[i][j][]*dp[i][j+]+p[i][j][]*dp[i+][j]+)/(-p[i][j][]);
}printf("%.3lf\n",dp[][]);
}
T2:hdu4405
有0-n个格子,初始点在0,终点是>=n,每走一步之前都要丢一次六个面的色子,标上1-6,扔到几就走几步,当然色子是等概率出现数字的,还有就是中间某一点可能和其它的一点联通,比如a和b联通,当我处于a时,就可以直接飞到b(不用耗费步数),最后问走到终点时所扔色子次数的期望。
这题显然期望DP,显然期望DP的初始值为dp[n]=0,做期望DP要记住一点,要从距离结果状态较近的状态推到结果状态较远的状态。所以不要从dp[0]开始推哦!
然后如果我们发现某个点能否飞到其他店那么显然dp[i]=dp[fly[i]]
否则dp[i]=sum(d[i+j]/6)+1(1<=j<=6)
然后暴力推就好啦
#include<cstdio>
#include<cstring>
using namespace std;
int fly[];
double dp[];
int n,m,x,y;
int main(){
while(~scanf("%d%d",&n,&m)){
if(n==&&m==)break;
memset(dp,,sizeof(dp));
memset(fly,,sizeof(fly));
for(int i=;i<=m;i++)scanf("%d%d",&x,&y),fly[x]=y;
for(int i=n-;i>=;i--){
if(fly[i])dp[i]=dp[fly[i]];
else for(int j=;j<=;j++)dp[i]+=(dp[i+j]+)/;
}printf("%.4lf\n",dp[]);
}
}
T3:poj2096
题意:有n类bug和s个子系统,bug数量不限,且每天只能发现一个bug,要求的是当在s个子系统中发现n类bug时所需要天数的期望(平均天数)。
emmm这道题目首先我们设置一下初始状态dp[n][s]=0,dp[i][j]表示从j个子系统中发现i个bug的状态转移到s个子系统中发现n个bug的状态的期望天数
那么显然dp[i][j]会从以下4个地方转移:dp[i][j],dp[i+1][j],dp[i+1][j+1],dp[i][j+1]
概率也很好算的QAQ,然后我们就能得到下面的式子:
dp[i][j]=dp[i+1][j+1]*((n-i)*(s-j)/n/s)+dp[i][j+1]*(i*j/n/s)+dp[i+1][j]*((n-i)*j/n/s)+dp[i][j]*(i*j/n/s)+1
因为递推式不能重复出现同一个变量,所以我们移项再化简,合并同类项得到下面的式子:
dp[i][j]=((dp[i+1][j+1]*(n-i)*(s-j)+dp[i][j+1]*i*(s-j)+dp[i+1][j]*(n-i)*j)/(1.0*n*s)+1)/(1-(1.0*i*j/n/s));
就刷完啦!QAQ
#include<cstdio>
using namespace std;
double dp[][];
int n,s;
int main(){
scanf("%d%d",&n,&s);
for(int i=n;i>=;i--)
for(int j=s;j>=;j--){
if(i==n&&j==s)continue;
dp[i][j]=((dp[i+][j+]*(n-i)*(s-j)+dp[i][j+]*i*(s-j)+dp[i+][j]*(n-i)*j)/(1.0*n*s)+)/(-(1.0*i*j/n/s));
}
printf("%.4lf\n",dp[][]);
}
T4:有2^n支队,现在要进行n次比赛,并且按次序进行比赛并淘汰,胜利的队继续按次序比赛并淘汰,比如1,2,3,4进行比赛,第一轮1和2比,3和4比,假如1和3胜利了,那么第二轮1和3继续比,2,4淘汰。最后问最有可能胜利的队伍是哪一支。输出数据以-1结束
这个题目很显然概率DP,注意:概率DP跟期望DP不一样,概率DP是正着推。0.0
方程很水emmmm:f[i][j]+=f[i-1][j]*(f[i-1][k]*beat[j][k])
但是我们的k有限制的QAQ因为按照顺序比赛,比如说1号队伍和3号队伍在第一局并不能比赛。
所以我们要找到一个性质:如果j>>(i-1)==k>>(i-1)^1那么第i局j和k就是在同一组的
然后就轻松啦QAQ
#include<cstdio>
#include<cstring>
using namespace std;
double f[][];
double beat[][],ans;
int n,ansnum;
int main(){
while(~scanf("%d",&n)&&n!=-){memset(beat,,sizeof(beat));
for(int i=;i<(<<n);i++)for(int j=;j<(<<n);j++)scanf("%lf",&beat[i][j]);
memset(f,,sizeof(f));ans=ansnum=;
for(int i=;i<(<<n);i++)f[][i]=;
for(int i=;i<=n;i++)
for(int j=;j<(<<n);j++)
for(int k=;k<(<<n);k++){
if((j>>(i-))==((k>>(i-))^))f[i][j]+=f[i-][j]*(f[i-][k]*beat[j][k]);
}
for(int i=;i<(<<n);i++)if(f[n][i]>ans)ans=f[n][i],ansnum=i;
printf("%d\n",ansnum+);
}
}
概率DP入门学习QAQ的更多相关文章
- HDU 3853 LOOPS 概率DP入门
LOOPS Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 125536/65536 K (Java/Others)Total Sub ...
- HDU 4405:Aeroplane chess(概率DP入门)
http://acm.split.hdu.edu.cn/showproblem.php?pid=4405 Aeroplane chess Problem Description Hzz loves ...
- 概率dp入门
概率DP主要用于求解期望.概率等题目. 转移方程有时候比较灵活. 一般求概率是正推,求期望是逆推.通过题目可以体会到这点. poj2096:Collecting Bugs #include <i ...
- poj 2096 Collecting Bugs 概率dp 入门经典 难度:1
Collecting Bugs Time Limit: 10000MS Memory Limit: 64000K Total Submissions: 2745 Accepted: 1345 ...
- 洛谷P2719 搞笑世界杯 题解 概率DP入门
作者:zifeiy 标签:概率DP 题目链接:https://www.luogu.org/problem/P2719 我们设 f[n][m] 用于表示还剩下n张A类票m张B类票时最后两张票相同的概率, ...
- 树形DP入门学习
这里是学习韦神的6道入门树形dp进行入门,本来应放在day12&&13里,但感觉这个应该单独放出来好点. 这里大部分题目都是参考的韦神的思想. A - Anniversary part ...
- POJ 2096-Collecting Bugs(概率dp入门)
题意: 有n种bug和s种系统bug,每天发现一种bug(可能已经发现过了)所有种bug被发现的概率相同,求所有bug被发现的期望天数. 分析: dp[i][j]发现i种bug,j种系统bug期望天数 ...
- HDU 3853-loop(概率dp入门)
题意: r*c个方格,从(1,1)开始在每个方格可释放魔法(消耗能量2)以知,释放魔法后可能在原地.可能到达相邻的下面格子或右面格子,给出三者的概率 求要到达(R,C)格子,要消耗能量的期望值. 分析 ...
- hdu4405概率dp入门
Aeroplane chess Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
随机推荐
- == 和equal的区别?-005
1,== 和equal的区别? ==比较两个值是否相等,equal比较对对象的引用是否一致 举例: int a = 2; int b = 2; System.err.println(a == b);/ ...
- bzoj2676 Contra
题意: 给定N,R,Q,S 有N个关卡,初始有Q条命,且任意时刻最多只能有Q条命 每通过一个关卡,会得到u分和1条命,其中u=min(最近一次连续通过的关数,R) 若没有通过这个关卡,将失去一条命,并 ...
- AIM Tech Round (Div. 2) B
B. Making a String time limit per test 1 second memory limit per test 256 megabytes input standard i ...
- 题解【luoguP1525 NOIp提高组2010 关押罪犯】
题目链接 题解 算法: 一个经典的并查集 但是需要用一点贪心的思想 做法: 先将给的冲突们按冲突值从大到小进行排序(这很显然) 然后一个一个的遍历它们 如果发现其中的一个冲突里的两个人在同一个集合里, ...
- TCP ------ TCP三次握手(建立连接)及其相关内容
1.TCP客户端要连接到TCP服务器,需要经过三个过程: 以下是通过 Wireshark 抓取的三次握手数据包 → [SYN] Seq= Win= Len= MSS= → [SYN, ACK] Seq ...
- centos7-每天定时备份 mysql数据库
centos7-每天定时备份 mysql数据库 第一步:编写数据库备份脚本database_mysql_shell.sh #!/bin/bash DATE=`date +%Y%m%d%H%M` #ev ...
- Android 命名规范 (转)
刚接触android的时候,命名都是按照拼音来,所以有的时候想看懂命名的那个控件什么是什么用的,就要读一遍甚至好几遍才知道,这样的话,在代码的审查和修改过程中就会浪费不少不必要的时间.如果就是我一个人 ...
- IIS---HTTP 错误 500.19 - Internal Server Error 的解决方法
在验证IIS是否安装成功,测试了一个页面,报500.19错误 感谢:http://www.cnblogs.com/imjustice/archive/2011/04/04/2198116.html 图 ...
- 51Nod 1090 3个数之和
Input示例 7 -3 -2 -1 0 1 2 3 Output示例 -3 0 3 -3 1 2 -2 -1 3 -2 0 2 -1 0 1 #include "bits/stdc++.h ...
- vijos 1002 简单压缩+DP
描述 在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧.在桥上有一些石子,青蛙很讨厌踩在这些石子上.由于桥的长度和青蛙一次跳过的距离都是正整数,我们可以把独木桥上青蛙可能到达的点看成数轴上 ...