表示对概率和期望还不是很清楚定义。

目前暂时只知道概率正推,期望逆推,然后概率*某个数值=期望。

为什么期望是逆推的,例如你求到某一个点的概率我们可以求得,然后我们只要运用dp从1~n每次都加下去就好了,这样求出来的就是最后的概率。那么期望呢,就是这个概率*数值就行了。但是有时候这么绕来绕去太麻烦了,我们干脆就逆过来。然后我们发现,根据期望的定义,逆过来以后反正做结果并没有太大的改变,dp从n~1就可以了,并且每次都加上数值,然后在for的途中,这个数值是会不断的乘以概率的,所以期望适合用逆推的方法。

题目列表:

①LightOJ 1030 基础题(一)

②Light OJ 1038 基础题 (二)

③Light OJ 1079 背包+概率(三)

④Light OJ 1104 生日悖论(四)

⑤Light OJ 1248 筛子问题(五)

⑥Light OJ 1265 基础题(四)

一:light OJ 1030 基础题

题目大意:有n个点,每个点有一个val,从1开始出发,到底n个点,每次掷骰子,求到第n个点的期望val是多少?

思路:可以知道对于每个位置,下一个位置只能是后n-i个,所以从这个pos得到的val的期望f(i) = (f(i + 1) + f(i + 2) + … + f(i + 6)) / 6,如果这个位置后不足6,f(i) = (f(i + 1) + … + f(n)) / (n - i)。

期望的代码

//看看会不会爆int! 或者绝对值问题。
#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define ALL(a) a.begin(), a.end()
const int maxn = + ;
int n;
double dp[maxn];
int a[maxn]; int main(){
int T; cin >> T;
for (int t = ; t <= T; t++){
scanf("%d", &n);
memset(dp, , sizeof(dp));
for (int i = ; i <= n; i++){
scanf("%lf", dp + i);
}
for (int i = n; i >= ; i--){
int k = min(, n - i);
for (int j = ; j <= k; j++){
dp[i] += (dp[i + j]) * 1.0 / k;
}
}
printf("Case %d: %f\n", t, dp[]);
}
return ;
}

当然这道题也可以用概率的代码来写,看这个人的博客吧http://www.cnblogs.com/WABoss/p/5296629.html

学习:懂得基本的期望和概率的知识

二:Light OJ 1038 基础题

思路:预处理即可

//看看会不会爆int!数组会不会少了一维!
//取物问题一定要小心先手胜利的条件
#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define ALL(a) a.begin(), a.end()
#define pb push_back
#define mk make_pair
#define fi first
#define se second
const int maxn = 1e5 + ;
double dp[maxn]; int main(){
for (int i = ; i <= maxn - ; i++){
int cnt = ;
double sum = ;
for (int j = ; j * j <= i; j++){
if (i % j == ){
sum += dp[j]; cnt++;
if (j * j != i){
sum += dp[i / j]; cnt++;
}
}
}
sum += cnt;
dp[i] = sum / (cnt - );
}
int t; cin >> t;
for (int i = ; i <= t; i++){
int n; scanf("%d", &n);
printf("Case %d: %.12f\n", i, dp[n]);
}
return ;
}

学习:预处理技能

三:Light oj1079

题目大意:抢银行;一个安全概率p,和银行的个数n;接下去给出每个银行可以抢到的钱,还有抢劫这个银行被抓的概率;问在被抓的概率小于等于p的情况下,最多抢到多少钱;

思路:定义dp[i]目前拿了i元还没有被抓住的最大概率

//看看会不会爆int!数组会不会少了一维!
//取物问题一定要小心先手胜利的条件
#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define ALL(a) a.begin(), a.end()
#define pb push_back
#define mk make_pair
#define fi first
#define se second
const double eps = 1e-;
const int maxn = + ;
double dp[maxn * maxn];///目前拿了j元还没有被抓住的最大概率
int n;
pair<int, double> p[maxn]; int main(){
int kase = ;
int t; cin >> t;
while(t--){
memset(dp, , sizeof(dp));
memset(p, , sizeof(p));
double pro; int sum = ;
scanf("%lf %d", &pro, &n);
for (int i = ; i <= n; i++){
int val; double t;
scanf("%d%lf", &val, &t);
p[i] = mk(val, t);
sum += val;
}
dp[] = ;
for (int i = ; i <= n; i++){
for (int j = sum; j >= p[i].first; j--){
dp[j] = max(dp[j - p[i].first] * ( - p[i].second), dp[j]);
}
}
int ans = ;
for (int i = ; i <= sum; i++){
///printf("%.12f\n", dp[i]);
if (pro - + dp[i] > eps){
ans = i;
}
}
printf("Case %d: %d\n", ++kase, ans);
}
return ;
}

四:生日悖论

题目大意:给你n天,至少有几个人来参加,生日为同一天的概率超过50%?

思路:反过来定义dp[i]表示生日都不相同的概率即可。

//看看会不会爆int!数组会不会少了一维!
//取物问题一定要小心先手胜利的条件
#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define ALL(a) a.begin(), a.end()
#define pb push_back
#define mk make_pair
#define fi first
#define se second
const double eps = 1e-;
const int maxn = 1e5 + ;
double dp[maxn];///生日都不相同的概率 int solve(int n){
memset(dp, , sizeof(dp));
dp[] = 1.0;
for (int i = ; i <= n; i++){
dp[i] = dp[i - ] * (1.0 * (n - i + ) / n);
if ( - dp[i] >= 0.5) return i-;
}
} int main(){
int kase = ;
int t; cin >> t;
while (t--){
int n; scanf("%d", &n);
printf("Case %d: %d\n", ++kase, solve(n));
}
return ;
}

五:Light oj 1248

题目大意:给你n个面的东西,投掷,每个面出现至少一次的概率?

也可以看这个人的http://blog.csdn.net/u011686226/article/details/39928597

定义:dp[i]表示还需要扔i个面所需要投掷次数的期望值。然后每一次投掷是有两种可能性,一种是在已经出现过的面中,另一种是在没有出现过的面中,所以我们可以定义dp[i] = i/n * dp[i] + (n-i)/n * dp[i + 1] + 1;所以移项就好了。

如果想要简便一点想的话,就是6*1+6*(1/2)+6*(1/3)+6*(1/4)+6*(1/5)+6*(1/6)。

不过我还是根据期望的定义来写了。。。先算出概率,再求加权和

//看看会不会爆int!数组会不会少了一维!
//取物问题一定要小心先手胜利的条件
#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define ALL(a) a.begin(), a.end()
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define haha printf("haha\n")
const int maxn = 1e5 + ;
int n;
double dp[maxn];///定义,目前已经出现i种不同颜色的概率 int main(){
int t; cin >> t;
int kase = ;
while (t--){
scanf("%d", &n);
for (int i = ; i <= n; i++){
dp[i] = 1.0 / i;
}
double ans = ;
for (int i = ; i <= n; i++){
ans += dp[i] * n * 1.0;
}
printf("Case %d: %.12f\n", ++kase, ans);
}
return ;
}

学习:期望的定义是:每个的概率*权值

六:lightOJ 1265

题目大意:有t个老虎,d个鹿,有以下操作

T-M T会吃掉M 
T-D T会吃掉D 
D-D Nothing 
M-D M可以选择杀与不杀D 
T-T 两只T会互相残杀(Two Die)

可以看看这个人的http://blog.csdn.net/challengerrumble/article/details/52528951

思路一:定义dp[i][j]表示还有i只老虎,j只鹿的概率,转移就好了

//看看会不会爆int!数组会不会少了一维!
//取物问题一定要小心先手胜利的条件
#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define ALL(a) a.begin(), a.end()
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define haha printf("haha\n")
const int maxn = + ;
double dp[maxn][maxn];///还有i只老虎,j只鹿的概率
int n, m; int main(){
int T; cin >> T;
for (int kase = ; kase <= T; kase++){
scanf("%d%d", &n, &m);
if (n % == ) {printf("Case %d: %.10f\n", kase, 0.0); continue;}
memset(dp, , sizeof(dp));
dp[n][m] = ;
for (int i = n; i >= ; i--){
for (int j = m; j >= ; j--){
int sum = i * j + i * (i - ) / + i;///总可能性
if (sum == ) continue;
if (j != ) dp[i][j - ] += 1.0 * dp[i][j] * i * j / sum;
if (i >= ) dp[i - ][j] = 1.0 * dp[i][j] * i * (i - ) / / sum;
}
}
double ans = ;
for (int i = ; i <= m; i++) ans += dp[][i];
printf("Case %d: %.10f\n", kase, ans);
}
return ;
}

思路二:定义dp[i] = 目前有i只老虎,老虎全部死亡的概率

因为鹿对我们的存活没有影响,然后我们定义人从来都不杀鹿,这样可以让自己的存活率最大。

所以:

//看看会不会爆int!数组会不会少了一维!
//取物问题一定要小心先手胜利的条件
#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define ALL(a) a.begin(), a.end()
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define haha printf("haha\n")
const int maxn = + ;
double dp[maxn];
int n, m; int main(){
int T; cin >> T;
for (int kase = ; kase <= T; kase++){
scanf("%d%d", &n, &m);
if (n % == ){
printf("Case %d: %.10f\n", kase, 0.0);
continue;
}
dp[n] = 1.0;
for (int i = n; i >= ; i--){
int sum = i * (i - ) / + i;
if (!sum) continue;
if (i >= ) dp[i - ] = dp[i] * i * (i - ) / / sum;
}
printf("Case %d: %.10f\n", kase, dp[]);
}
return ;
}

学习:需要懂得目前哪些东西是无关变量,再加上一点的贪心即可

七:

八:

九:

概率dp+期望dp 题目列表(一)的更多相关文章

  1. 概率和期望dp

    概率和期望dp 概率和期望好神啊,完全不会. 网上说概率要顺着推,期望要逆着推,然而我目前做的概率期望题正好都与此相反2333   概率: 关于概率:他非常健康 初中概率题非常恐怖.现在来思考一道题: ...

  2. 【CodeForces】913 F. Strongly Connected Tournament 概率和期望DP

    [题目]F. Strongly Connected Tournament [题意]给定n个点(游戏者),每轮游戏进行下列操作: 1.每对游戏者i和j(i<j)进行一场游戏,有p的概率i赢j(反之 ...

  3. 概率与期望dp相关

    概率与期望dp 概率 某个事件A发生的可能性的大小,称之为事件A的概率,记作P(A). 假设某事的所有可能结果有n种,每种结果都是等概率,事件A涵盖其中的m种,那么P(A)=m/n. 例如投掷一枚骰子 ...

  4. 【算法学习笔记】概率与期望DP

    本文学习自 Sengxian 学长的博客 之前也在CF上写了一些概率DP的题并做过总结 建议阅读完本文再去接着阅读这篇文章:Here 前言 单纯只用到概率的题并不是很多,从现有的 OI/ACM 比赛中 ...

  5. 【BZOJ-4008】亚瑟王 概率与期望 + DP

    4008: [HNOI2015]亚瑟王 Time Limit: 20 Sec  Memory Limit: 512 MBSec  Special JudgeSubmit: 832  Solved: 5 ...

  6. [CF697D]Puzzles 树形dp/期望dp

    Problem Puzzles 题目大意 给一棵树,dfs时随机等概率选择走子树,求期望时间戳. Solution 一个非常简单的树形dp?期望dp.推导出来转移式就非常简单了. 在经过分析以后,我们 ...

  7. 概率及期望DP小结

    资源分享 26 个比较概率大小的问题 数论小白都能看懂的数学期望讲解 概念 \(PS\):不需要知道太多概念,能拿来用就行了. 定义 样本(\(\omega\)):一次随机试验产生的一个结果. 样本空 ...

  8. hdu4405Aeroplane chess(概率与期望dp)

    Aeroplane chess Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)T ...

  9. BZOJ 3566 [SHOI2014]概率充电器 ——期望DP

    期望DP. 补集转化,考虑不能被点亮的情况, 然后就是三种情况,自己不能亮,父亲不能点亮它,儿子不能点亮它. 第一次计算比较容易,第二次计算的时候需要出去第一次的影响,因为一条线只能传导一次 #inc ...

随机推荐

  1. JavaScript筑基篇(一)->变量、值与对象

    说明 JavaScript中变量.值.对象的理解.本文为了简化理解,前半部分暂时刨除与执行上下文的相关概念.另外本文是个人的见解,如有疑问或不正支持,欢迎提出指正和讨论! 目录 前言 参考来源 变量与 ...

  2. 软件工程 作业part1

    自我介绍 老师您好,我叫宋雨,本科在长春理工大学,专业是计算机科学与技术. 1.回想一下你曾经对计算机专业的畅想:当初你是如何做出选择计算机专业的决定?你认为过去接触的课程是否符合你对计算机专业的期待 ...

  3. 策略模式,ASP.NET实现

    策略模式,ASP.NET实现 using System; using System.Collections.Generic; using System.Linq; using System.Web; ...

  4. TCP系列23—重传—13、RACK重传

    一.RACK概述 RACK(Recent ACKnowledgment)是一种新的基于时间的丢包探测算法,RACK的目的是取代传统的基于dupthresh门限的各种快速重传及其变种.前面介绍的各种基于 ...

  5. OSG学习:矩阵变换节点示例

    #include<osgViewer\Viewer> #include<osg\Node> #include<osg\Geode> #include<osg\ ...

  6. Maximum execution time of 30 seconds exceeded解决办法

    Maximum execution time of 30 seconds exceeded,今天把这个错误的解决方案总结一下: 简单总结一下解决办法: 报错一:内存超限,具体报错语句忘了,简单说一下解 ...

  7. 安装django 提示ImportError: No module named setuptools

    安装django前要先安装setuptools 先安装一些必要的包,否则会报错:Python build finished, but the necessary bits to build these ...

  8. 什么是Oracle的分区表 (转 作者 陈字文)

    假设我们现在正在酝酿经营一家图书馆,最初,我们只有十本书提供给大家来阅读和购买.对于十本书而言,我们可能只需要一个书架格子将其作为保存这十本书的容器就足够了,因为任何一个人都可以很轻松的扫一眼就可以将 ...

  9. [OS] 死锁相关知识点以及银行家算法详解

    因此我们先来介绍一下死锁: 死锁特征 当出现死锁时,进程永远不能完成,并且系统资源被阻碍使用,阻止了其他作业开始执行.在讨论处理死锁问题的各种方法之前,先深入讨论一下死锁的特征. ·必要条件 (1)互 ...

  10. RT-thread内核之小内存管理算法

     一.动态内存管理 动态内存管理是一个真实的堆(Heap)内存管理模块,可以在当前资源满足的情况下,根据用户的需求分配任意大小的内存块.而当用户不需要再使用这些内存块时,又可以释放回堆中供其他应用分配 ...