做完这道题才略微感觉自己懂了一点关于概率与期望的知识QAQ。。。

一:关于概率与期望的定义

转载节选于blog

1、什么是数学期望?

数学期望亦称期望、期望值等。在概率论和统计学中,一个离散型随机变量的期望值是试验中每一次可能出现的结果的概率乘以其结果的总和。

这是什么意思呢?假如我们来玩一个游戏,一共52张牌,其中有4个A。我们1元钱赌一把,如果你抽中了A,那么我给你10元钱,否则你的1元钱就输给我了。在这个游戏中,抽中的概率是113(452)

,结果是赢10元钱;抽不中概率是1213,结果是亏1元钱。那么你赢的概率,也就是期望值是−213。这样,你玩了很多把之后,一算账,发现平均每把会亏−213

元。

一般在竞赛中,若X是一个离散型的随机变量,可能值为x1,x2

……,对应概率为p1,p2……,概率和为1,那么期望值E(X)=∑ipixi

对于数学期望,我们还应该明确一些知识点:

(1)期望的“线性”性质。对于所有满足条件的离散型的随机变量X,Y和常量a,b,有:E(aX+bY)=aE(x)+bE(y)

类似的,我们还有E(XY)=E(X)+E(Y)

(2)全概率公式 假设{Bn∣n=1,2,3,...

}是一个“概率空间有限或可数无限”的分割,且集合Bn

是一个“可数集合”,则对于任意事件A有:

P(A)=∑nP(A∣Bn)P(Bn)

(3)全期望公式 E(Y)=E(E(Y∣X))=∑iP(X=xi)E(Y∣X=xi)

2、数学期望怎么用?

确实,数学期望在数学的范围里是一个较为复杂,但是却十分有用的一个部分。

但是题型类型多,花样也多,有时无从下手。明知是数学期望,却找不到正确的算法解决问题。

于是,我们来分析一下:

(1)对于很大一部分的期望问题,递推是个好帮手。我们一般在草稿纸上,把题目中隐含的期望值之间的关系,然后经过计算等方法,找出一个递推式。这个递推式,不要求我们枚举每一种可能(不然就没有用递推的意义了),而是根据一些已有的,或是可以直接简单地推算出的期望值,算出其他状态下的期望。这个道理道理大家也都明白,可是有时是很难找到递推式的。这时,我们就应该用我们之前讲过的期望的定义——E(X)=∑ipixi

,然后再结合期望的“线性”性质和全概率、全期望公式,一步步地像“剥笋皮”一样,找到问题的核心,这样效果往往很好。

(2)另外,有决策、满足最优子结构的期望问题,我们还可以考虑人们常常与“递推”弄混的“动态规划”。这里,我们一般用期望表示状态,期望的正负高低,就能决定这个状态的优和劣。

(3)对于上述两种方法都不能解决的,这也算是比较少了。这时,常见的尝试方法之一就是高斯消元法。我们可以先尝试建立一个线性方程组,然后进行高斯消元等操作

其实以上的理论我看着也。。。。

也给大家推荐一个blog,里面有许多的关于这个专题的详解和例题。

二:关于此题。。。

1、题目大意:

有一个v个节点的无向图,共有e条边,牛牛应该上n节课,第i课同时在c[i]与d[i]进行,牛牛都可以去上,唯一的区别是在c[i]上课不需要申请而在d[i]则需要,并且仅有m次机会申请,通过概率为p[i];要求的就是牛牛移动的体力值总和的期望值最小。

2、大概思路

(1)初始化

首先就是对于这v个点之间的最短路径进行处理,因为仅仅有300个点,所以即使用Floyd也不会爆掉,但是感人感觉用v遍优先队列优化的Dij会更稳一些,这里给出代码

void dij(int x)
{
memset(vis,false,sizeof(vis));
for(int i=1;i<=v;i++)
dis[x][i]=INF;
q.push(mp(0,x));
dis[x][x]=0;
while(!q.empty())
{
int y=q.top().second;
q.pop();
if(vis[y]) continue;
vis[y]=true;
for(int i=head[y];i;i=nxt[i])
if(dis[x][ver[i]]>dis[x][y]+eage[i])
{
dis[x][ver[i]]=dis[x][y]+eage[i];
q.push(mp(-dis[x][ver[i]],ver[i]));
}
}
}

对于路径储存,有兴趣的可以学一下vector+pair储存blog

其次便是对于dp数组f的初始化了

f[i][j][k]表示在前i节课,申请j次,且用k表示第i次有无申请;一定要注意这个地方k表示的不是是否申请成功而是有无申请,在这个地方卡了好久orz。

因为要求最小值所以把f都赋值成极大值

f[1][0][0]与f[1][1][1]以为是初始位置所以都是0。

此外还要注意在第i次的时候要先处理一下j=0的情况

即f[i][0][0]=f[i-1][0][0]+dis[c[i-1]][c[i]];

牛牛从未申请过所以直接拿f[i-1][0][0]加c[i-1]与c[i]的距离就可以了。

(2)算法主体

f[i][j][0]就可以等于以下两种的较小值

  1. 上一次未申请的f[i-1][j][0]加上c[i]与c[i-1]的距离;
  2. 上一次申请的f[i-1][j][1]有p[i-1]的概率申请成功,有(1-p[i-1])的概率申请失败,所以应该为f[i-1][j][1]与p[i-1]dis[c[i]][d[i-1]]+(1-p[i-1])dis[c[i]][c[i-1]]的和。

同样的f[i][j][1]也有p[i]的概率成功,就可以等于以下两种的较小值

  1. 上一次未申请的f[i-1][j-1][0]+p[i]dis[c[i-1]][d[i]]+(1-p[i])dis[c[i-1]][c[i]];
  2. 上一次申请的f[i-1][j-1][1]+p[i](p[i-1]dis[d[i-1]][d[i]]+(1-p[i-1])dis[c[i-1]][d[i]])+(1-p[i])(p[i-1]dis[d[i-1]][c[i]]+(1-p[i-1])dis[c[i-1]][c[i]]。

(3)输出

求出前n个中申请1-m次的最小值

for(int i=0;i<=m;i++)
ans=min(ans,min(f[n][i][0],f[n][i][1]));
printf("%.2lf",ans);

3、CODE

#include<bits/stdc++.h>
#define ll long long
#define pb push_back
#define mp make_pair
using namespace std;
const int N=9e4;
const int INF=1e9;
int n,m,v,e,tot,head[2*N+5],nxt[2*N+5],eage[2*N+5],ver[2*N+5],c[2005],d[2005];
double p[2005],f[2005][2005][2],dis[2005][2005],ans=INF;
bool vis[2005];
priority_queue<pair<int,int> > q;
void add(int x,int y,int t)
{
ver[++tot]=y,eage[tot]=t;
nxt[tot]=head[x],head[x]=tot;
}
void dij(int x)
{
memset(vis,false,sizeof(vis));
for(int i=1;i<=v;i++)
dis[x][i]=INF;
q.push(mp(0,x));
dis[x][x]=0;
while(!q.empty())
{
int y=q.top().second;
q.pop();
if(vis[y]) continue;
vis[y]=true;
for(int i=head[y];i;i=nxt[i])
if(dis[x][ver[i]]>dis[x][y]+eage[i])
{
dis[x][ver[i]]=dis[x][y]+eage[i];
q.push(mp(-dis[x][ver[i]],ver[i]));
}
}
}
void init()
{
scanf("%d%d%d%d",&n,&m,&v,&e);
for(int i=1;i<=n;i++)
scanf("%d",&c[i]);
for(int i=1;i<=n;i++)
scanf("%d",&d[i]);
for(int i=1;i<=n;i++)
scanf("%lf",&p[i]);
for(int i=1,x,y,t;i<=e;i++)
{
scanf("%d%d%d",&x,&y,&t);
add(x,y,t);
add(y,x,t);
}
for(int i=0;i<=n;i++)
for(int j=0;j<=m;j++)
f[i][j][0]=f[i][j][1]=INF;
f[1][0][0]=f[1][1][1]=0;
}
int main()
{
init();
for(int i=1;i<=v;i++)
dij(i);
for(int i=2;i<=n;i++)
{
f[i][0][0]=f[i-1][0][0]+dis[c[i-1]][c[i]];
for(int j=1;j<=min(i,m);j++)
{
f[i][j][0]=min(f[i][j][0],min(f[i-1][j][0]+dis[c[i]][c[i-1]],f[i-1][j][1]+p[i-1]*dis[c[i]][d[i-1]]+(1-p[i-1])*dis[c[i]][c[i-1]]));
f[i][j][1]=min(f[i-1][j-1][0]+p[i]*dis[c[i-1]][d[i]]+(1-p[i])*dis[c[i-1]][c[i]],f[i-1][j-1][1]+p[i]*(p[i-1]*dis[d[i-1]][d[i]]+(1-p[i-1])*dis[c[i-1]][d[i]])+(1-p[i])*(p[i-1]*dis[d[i-1]][c[i]]+(1-p[i-1])*dis[c[i-1]][c[i]])); }
}
for(int i=0;i<=m;i++)
ans=min(ans,min(f[n][i][0],f[n][i][1]));
printf("%.2lf",ans);
return 0;
}

题解 P1850 [NOIP2016 提高组] 换教室的更多相关文章

  1. Luogu P1850 [NOIp2016提高组]换教室 | 期望dp

    题目链接 思路: <1>概率与期望期望=情况①的值*情况①的概率+情况②的值*情况②的概率+--+情况n的值*情况n的概率举个例子,抛一个骰子,每一面朝上的概率都是1/6,则这一个骰子落地 ...

  2. [NOIp2016提高组]换教室

    题目大意: 有n节课,第i节课在c[i]上课,同时d[i]也有一节课d[i]. 你有权利向教务处发出m次申请把自己的教室改到d[i],相应的批准概率是k[i]. 教室是图上的一些点,其中每条边都有边权 ...

  3. 洛谷 1850 NOIP2016提高组 换教室

    [题解] 先用floyed处理出两点间的最短路. 设f[i][j][k]表示走到第i个教室,总共换了j次,当前换或者不换,期望的最小移动距离. 分情况讨论来转移即可. #include<cstd ...

  4. 【题解】NOIP2016提高组 复赛

    [题解]NOIP2016提高组 复赛 传送门: 玩具谜题 \(\text{[P1563]}\) 天天爱跑步 \(\text{[P1600]}\) 换教室 \(\text{[P1850]}\) 组合数问 ...

  5. 【题解】NOIP2016 提高组 简要题解

    [题解]NOIP2016 提高组 简要题解 玩具迷题(送分) 用异或实现 //@winlere #include<iostream> #include<cstdio> #inc ...

  6. NOIP2016提高组解题报告

    NOIP2016提高组解题报告 更正:NOIP day1 T2天天爱跑步 解题思路见代码. NOIP2016代码整合

  7. 【题解】NOIP2015提高组 复赛

    [题解]NOIP2015提高组 复赛 传送门: 神奇的幻方 \([P2615]\) 信息传递 \([P2661]\) 斗地主 \([P2668]\) 跳石头 \([P2678]\) 子串 \([P26 ...

  8. 【题解】NOIP2017 提高组 简要题解

    [题解]NOIP2017 提高组 简要题解 小凯的疑惑(数论) 不讲 时间复杂度 大力模拟 奶酪 并查集模板题 宝藏 最优解一定存在一种构造方法是按照深度一步步生成所有的联通性. 枚举一个根,随后设\ ...

  9. [日记&做题记录]-Noip2016提高组复赛 倒数十天

    写这篇博客的时候有点激动 为了让自己不颓 还是写写日记 存存模板 Nov.8 2016 今天早上买了两个蛋挞 吃了一个 然后就做数论(前天晚上还是想放弃数论 但是昨天被数论虐了 woc noip模拟赛 ...

随机推荐

  1. 启动spring boot项目时报错:java.lang.ClassNotFoundException: javax.servlet.Filter

    <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring- ...

  2. Win10安装MySQL5和MySQL8

    1. 下载数据库,配置环境变量 因为是安装两个MySQL数据库,端口号要不一样,MySQL默认端口号是3306,建议先配置非默认端口号,以免出现问题 1.1 官网下载5.7和8.0的压缩包 我下载的是 ...

  3. LeetCode 617. 合并二叉树 Java

    给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠. 你需要将他们合并为一个新的二叉树.合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 ...

  4. Java数组学习之前基础小案例

    不多说,1天时间看完数组之前内容,这就靠代码的实践总结一下吧~~ 打印三角形 简单易懂,初学都会,就不注释了,前者为取巧的三角形实现方法,我注释了,直接上源码~~ public class Trian ...

  5. prometheus管理api

    健康检查:GET /-/healthy 准备检查:GET /-/ready 停止服务:PUT|POST /-/quit 重载配置文件 PUT|POST /-/reload reference mana ...

  6. [Java] Structs

    背景 基于MVC的WEB框架 在表示层过滤访问请求并处理 步骤 在eclipse中创建Web动态项目 导入相关jar包到WEB-INF/lib 在WEB-INF目录下新建web.xml,配置Filte ...

  7. canal 环境搭建 canal 与kafka通信(三)

    canal 占用了生产者 .net core端 使用消费者获取canal 消息 安装 Confluent.Kafka  demo使用 1.3.0 public static void Consumer ...

  8. mysql 配置文件概述

    mysql 配置文件概述 mysql 配置文件 mysql 的配置文件为 /etc/my.cnf 配置文件查找次序:若在多个配置文件中均有设定,则最后找到的最终生效 /etc/my.cnf --> ...

  9. 7.12-7.19 id、w、who、last、lastb、lastlog

    7.12-7.19 id.w.who.last.lastb.lastlog 目录 7.12 id:显示用户与用户组的信息 7.13 w:显示已登录用户信息 7.14 who:显示已登录用户信息 显示最 ...

  10. Mysql_源码包安装详细过程

    一.mysql安装 1.二进制安装 2.源码包安装 3.rpm包安装 1.源码包安装 1)上传或下载源码包 [root@db02 ~]# rz mysql-5.6.46.tar.gz 2)安装依赖 由 ...