ACM - 概率、期望题目 小结(临时)
概率DP求期望大多数都是全期望公式的运用。主要思考状态空间的划分以及状态事件发生的概率。问题可以分为无环和有环两类。无环一类多数比较简单,可以通过迭代或者记忆化搜索完成。有环一类略复杂,可以通过假设方程化简公式解决或者高斯消元求解。
POJ 2096 Collecting Bugs
http://poj.org/problem?id=2096
概率DP入门题,注意理解和状态的转移过程才能建立方程。
dp[i][j]表示已经找到i种系统的j种bug时达到目标状态时的期望,此时找到一个bug,可能仍属于原来i种系统j种bug,也可能是第i+1种系统j种bug,也可能是i种系统第j+1种bug,也可能是第i+1种系统第j+1种bug,不同情况有不同的概率。这是所谓的马尔柯夫过程。
#include <iostream> #include <cstdlib> #include <cstdio> #include <algorithm> #include <cstring> using namespace std; ][]; ][]; double r; int n,s; double dp(int i,int j) { if(vis[i][j]||i>n||j>s) return f[i][j]; vis[i][j]=true; f[i][j]=+(n-i)*j/r*dp(i+,j)+i*(s-j)/r*dp(i,j+)+(n-i)*(s-j)/r*dp(i+,j+); f[i][j]/=(-i*j/r); return f[i][j]; } int main() { scanf("%d%d",&n,&s); r=n*s; vis[n][s]=; f[n][s]=; printf(,)); ; }
UVa 11762 Race to 1
概率DP,马尔柯夫过程。
dp[i]表示i经过题目变换得到1的期望,这样dp[i]=(s[i]-p[i])/s[i]*dp[i]+sum{1/s[i]*dp[i/prime[i][j]]}其中s[i]表示1到i之间的素数个数,p[i]表示数字i
的质因子个数,prime[i][j]表示数字i的第j个质因子。
终止条件是dp[1]=0。因为1不需要变化就能得到1,所以期望的步骤数是0。
#include <iostream> #include <cstdlib> #include <cstdio> #include <algorithm> #include <cstring> #include <vector> #define maxn 1000000 using namespace std; ]; ]; vector<]; void init() { memset(is_prime,,sizeof(is_prime)); is_prime[]=; ; i<=maxn; ++i) if(is_prime[i]) { numb[i].push_back(i); for(int j=i+i; j<=maxn; j+=i) { is_prime[j]=false; numb[j].push_back(i); } } ; i<=maxn; ++i) ]+; ]; } ]; ]; int n; double dp(int x) { if(vis[x]) return f[x]; vis[x]=true; f[x]=; ; i<numb[x].size(); ++i) f[x]+=1.0/sum[x]*dp(x/numb[x][i]); f[x]/=(-((sum[x]-numb[x].size())/1.0/sum[x])); return f[x]; } int main() { ; scanf("%d",&T); f[]=; vis[]=; init(); while(T--) { scanf("%d",&n); printf("Case %d: %.10lf\n",++kase,dp(n)); } ; }
简单的概率DP,注意用记忆化搜索会爆栈。
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cstdlib> using namespace std; int n,m; ]; ],p; int main() { p=/6.0; while(scanf("%d%d",&n,&m)!=EOF) { if(!n&&!m) break; memset(move,,sizeof(move)); ; i<m; ++i) { int x,y; scanf("%d%d",&x,&y); move[x]=y; } memset(f,,sizeof(f)); ; i>=; --i) { if(move[i]) f[i]=f[move[i]]; else { f[i]=; ; j<=; ++j) f[i]+=p*f[i+j]; } } printf(]); } ; }
经典的简单概率DP,注意可能有到达自身概率是1的情况,这种地方不可能再达到别的地方,所以应该被忽略掉。
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cstdlib> using namespace std; ][][]; ][]; int n,m; int main() { while(scanf("%d%d",&n,&m)!=EOF) { memset(pro,,sizeof(pro)); memset(dp,,sizeof(dp)); ; i<=n; ++i) ; j<=m; ++j) scanf(],&pro[i][j][],&pro[i][j][]); ; --i) ; --j) { if(i==n&&j==m) continue; dp[i][j]=; ]==) dp[i][j]=; else { dp[i][j]+=pro[i][j][]*dp[i][j+]+pro[i][j][]*dp[i+][j]; dp[i][j]/=(-pro[i][j][]); } } printf(][]); } ; }
带环的概率DP。设dp[i]表示当前为i分时到结束游戏时的期望,这样dp[i]=r*dp[0]+∑pk*dp[i+x]。其中r表示第一二三个骰子分别取a,b,c时的概率即1/(k1*k2*k3)。pk表示三个骰子和为x时的概率。终止条件时i>=n时,dp[i]=0。我们的最终答案是dp[0],但是这里每次递推都需要用到dp[0],显然不符合动规的特点,是所谓有环。因此需要别的方法。
#include <iostream> #include <cstdio> #include <cstring> #include <vector> #include <queue> #include <algorithm> #define ll long long #define MAXN 30005 using namespace std; ],B[]; ]; int main() { int T; scanf("%d",&T); while(T--) { int n,k1,k2,k3,a,b,c; scanf("%d%d%d%d%d%d%d",&n,&k1,&k2,&k3,&a,&b,&c); double r=1.0/(k1*k2*k3); memset(A,,sizeof(A)); memset(B,,sizeof(B)); memset(pro,,sizeof(pro)); ; i<=k1; ++i) ; j<=k2; ++j) ; k<=k3; ++k) if(!(i==a&&j==b&&k==c)) pro[i+j+k]+=r; int s=k1+k2+k3; ; --i) { ; j<=s; ++j) { A[i]+=pro[j]*A[i+j]; B[i]+=pro[j]*B[i+j]; } A[i]+=r; B[i]++; } printf(]/(-A[])); } ; }
ZOJ 3582 Back to the Past
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4624
概率DP求期望。dp[i][j]表示两侧分别亮了i和j个灯,然后枚举当天左右两侧分别亮的灯数,这里要注意求概率,比如左右两侧分别亮了k1、k2个灯,那么该事件发生的概率是
C[n-i][k1]*pow(p,k1)*pow(1-p,n-i-k1)*C[n-j][k2]*pow(p,k2)*pow(1-p,n-j-k2),注意这里选择亮的灯的部分。记忆化搜索或者递推都可以解决。
#include <iostream> #include <cstdlib> #include <cstdio> #include <algorithm> #include <cstring> #include <string> #include <vector> #include <cmath> #define maxn 1000000 using namespace std; int n,m; double p; ][]; ][],pro[][]; ][]; void init() { pro[][]=pro[][]=; ; i<=*n; ++i) { pro[][i]=pro[][i-]*p; pro[][i]=pro[][i-]*(-p); } } double dp(int a,int b) { ; if(vis[a][b]) return f[a][b]; vis[a][b]=true; f[a][b]=; ; i<=n-a; ++i) ; j<=n-b; ++j) { &&j==)) f[a][b]+=C[n-a][i]*pro[][i+j]*C[n-b][j]*pro[][n*-a-b-i-j]*dp(a+i,b+j); } f[a][b]/=(-pro[][n*-a-b]); return f[a][b]; } int main() { C[][]=; ; i<=; ++i) { C[i][]=C[i][i]=; ; j<i; ++j) C[i][j]=C[i-][j]+C[i-][j-]; } while(scanf("%d%d%lf",&n,&m,&p)) { if(!n&&!m&&!p) break; init(); memset(vis,,sizeof(vis)); memset(f,,sizeof(f)); printf(,)); } ; }
ACM - 概率、期望题目 小结(临时)的更多相关文章
- [LnOI2019]加特林轮盘赌(DP,概率期望)
[LnOI2019]加特林轮盘赌(DP,概率期望) 题目链接 题解: 首先特判掉\(p=0/1\)的情况... 先考虑如果\(k=1\)怎么做到\(n^2\)的时间复杂度 设\(f[i]\)表示有\( ...
- 牛客网多校赛第9场 E-Music Game【概率期望】【逆元】
链接:https://www.nowcoder.com/acm/contest/147/E 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言524 ...
- [Nowcoder212D]禁书目录_概率期望
禁书目录 题目大意:清教需要定期给Index清除记忆,在此之前需要把当中的十万三千本禁书取出来......不幸的是,禁书一旦离开了Index就非常脆弱,具体来说,每一本禁书都有一个魔力值 ai ,其记 ...
- 51nod 1943 联通期望 题解【枚举】【二进制】【概率期望】【DP】
集合统计类期望题目. 题目描述 在一片大海上有 \(n\) 个岛屿,规划建设 \(m\) 座桥,第i座桥的成本为 \(z_i\),但由于海怪的存在,第 \(i\) 座桥有 \(p_i\) 的概率不能建 ...
- 【bzoj4832】[Lydsy2017年4月月赛]抵制克苏恩 概率期望dp
题目描述 你分别有a.b.c个血量为1.2.3的奴隶主,假设英雄血量无限,问:如果对面下出一个K点攻击力的克苏恩,你的英雄期望会受到到多少伤害. 输入 输入包含多局游戏. 第一行包含一个整数 T (T ...
- 【loj6191】「美团 CodeM 复赛」配对游戏 概率期望dp
题目描述 n次向一个栈中加入0或1中随机1个,如果一次加入0时栈顶元素为1,则将这两个元素弹栈.问最终栈中元素个数的期望是多少. 输入 一行一个正整数 n . 输出 一行一个实数,表示期望剩下的人数, ...
- bzoj 2969: 矩形粉刷 概率期望
题目: 为了庆祝新的一年到来,小M决定要粉刷一个大木板.大木板实际上是一个W*H的方阵.小M得到了一个神奇的工具,这个工具只需要指定方阵中两个格子,就可以把这两格子为对角的,平行于木板边界的一个子矩形 ...
- 【BZOJ3143】【HNOI2013】游走 && 【BZOJ3270】博物馆 【高斯消元+概率期望】
刚学完 高斯消元,我们来做几道题吧! T1:[BZOJ3143][HNOI2013]游走 Description 一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小 ...
- 【BZOJ-3270】博物馆 高斯消元 + 概率期望
3270: 博物馆 Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 292 Solved: 158[Submit][Status][Discuss] ...
随机推荐
- iOS高性能图片架构与设计
版权声明:本文由柯灵杰原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/157 来源:腾云阁 https://www.qclo ...
- IEnumerable接口的实现
对象要实现可以迭代需IEnumerable接口并实现GetEnumerator方法.一下简单例子 public class SPEnumerable<T> : IEnumerable { ...
- IoC 之 2.2 IoC 容器基本原理(贰)
2.2.1 IoC容器的概念 IoC容器就是具有依赖注入功能的容器,IoC容器负责实例化.定位.配置应用程序中的对象及建立这些对象间的依赖.应用程序无需直接在代码中new相关的对象,应用程序由IoC ...
- WebGL 入门-WebGL简介与3D图形学
什么是WebGL? WebGL是一项使用JavaScript实现3D绘图的技术,浏览器无需插件支持,Web开发者就能借助系统显卡(GPU)进行编写代码从而呈现3D场景和对象. WebGL基于OpenG ...
- 172. Factorial Trailing Zeroes -- 求n的阶乘末尾有几个0
Given an integer n, return the number of trailing zeroes in n!. Note: Your solution should be in log ...
- inout
在函数声明时就用inout代替var 这样以后可以在函数内部修改外面的值 类似于C语言的传入指针 func change (inout num:Int) { num = 10 } var a = 2 ...
- WCF学习
WCF初探-1:认识WCF MQ与Webservice的区别 Webservice 和MQ(MessageQueue)都是解决跨平台通信的常用手段,两者有哪些区别呢? 个人认为最本质的区别在于 Web ...
- DOM解析和SAX解析的区别
DOM解析和SAX解析的区别 博客分类: XML DOM SAX DOM解析和SAX解析的区别 No 区 别 DOM解析 SAX解析 1 操作 将所有文件读取到内存中形成DOM树,如果文件量过大,则 ...
- 解决tomcat部署多个虚拟机时报IllegalStateException: Web app root system property already set to 的问题
解决tomcat部署多个虚拟机时报IllegalStateException: Web app root system property already set to 的问题 在web.xml中添加如 ...
- ASP.NET MVC 输出字符串
@{Output.Write("<h1>输出字符串</h1>");}