题解 P1850 [NOIP2016 提高组] 换教室
做完这道题才略微感觉自己懂了一点关于概率与期望的知识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]就可以等于以下两种的较小值
- 上一次未申请的f[i-1][j][0]加上c[i]与c[i-1]的距离;
- 上一次申请的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]的概率成功,就可以等于以下两种的较小值
- 上一次未申请的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]]。
(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 提高组] 换教室的更多相关文章
- Luogu P1850 [NOIp2016提高组]换教室 | 期望dp
题目链接 思路: <1>概率与期望期望=情况①的值*情况①的概率+情况②的值*情况②的概率+--+情况n的值*情况n的概率举个例子,抛一个骰子,每一面朝上的概率都是1/6,则这一个骰子落地 ...
- [NOIp2016提高组]换教室
题目大意: 有n节课,第i节课在c[i]上课,同时d[i]也有一节课d[i]. 你有权利向教务处发出m次申请把自己的教室改到d[i],相应的批准概率是k[i]. 教室是图上的一些点,其中每条边都有边权 ...
- 洛谷 1850 NOIP2016提高组 换教室
[题解] 先用floyed处理出两点间的最短路. 设f[i][j][k]表示走到第i个教室,总共换了j次,当前换或者不换,期望的最小移动距离. 分情况讨论来转移即可. #include<cstd ...
- 【题解】NOIP2016提高组 复赛
[题解]NOIP2016提高组 复赛 传送门: 玩具谜题 \(\text{[P1563]}\) 天天爱跑步 \(\text{[P1600]}\) 换教室 \(\text{[P1850]}\) 组合数问 ...
- 【题解】NOIP2016 提高组 简要题解
[题解]NOIP2016 提高组 简要题解 玩具迷题(送分) 用异或实现 //@winlere #include<iostream> #include<cstdio> #inc ...
- NOIP2016提高组解题报告
NOIP2016提高组解题报告 更正:NOIP day1 T2天天爱跑步 解题思路见代码. NOIP2016代码整合
- 【题解】NOIP2015提高组 复赛
[题解]NOIP2015提高组 复赛 传送门: 神奇的幻方 \([P2615]\) 信息传递 \([P2661]\) 斗地主 \([P2668]\) 跳石头 \([P2678]\) 子串 \([P26 ...
- 【题解】NOIP2017 提高组 简要题解
[题解]NOIP2017 提高组 简要题解 小凯的疑惑(数论) 不讲 时间复杂度 大力模拟 奶酪 并查集模板题 宝藏 最优解一定存在一种构造方法是按照深度一步步生成所有的联通性. 枚举一个根,随后设\ ...
- [日记&做题记录]-Noip2016提高组复赛 倒数十天
写这篇博客的时候有点激动 为了让自己不颓 还是写写日记 存存模板 Nov.8 2016 今天早上买了两个蛋挞 吃了一个 然后就做数论(前天晚上还是想放弃数论 但是昨天被数论虐了 woc noip模拟赛 ...
随机推荐
- .NET Design Patterns
设计模式分组 GoF设计模式著作中的23种设计模式分为3组:创建型(Creational).结构型(Structural)和行为型(Behavional). 创建型 创建型处理对象构造和引用.它们将对 ...
- 加载usbserial驱动后,为什么adb不可用了?
某设备提供了USB串口功能,上位机(Host端)可以通过USB串口与之通信.对于Linux上位机,比如Ubuntu,自带usbserial驱动,当安装usbserial驱动后,上位机就会生成ttyU ...
- ln -s 新目录(最后一个目录新建images) 旧目录(删除最后的images目录)
sudo yum install libvirt virt-install qemu-kvm 默认安装会启用一个NAT模式的bridgevirbr0 启动激活libvirtd服务 systemctl ...
- OSI 七层参考模型与 TCP/IP 四层协议
OSI 七层参考模型 OSI (Open System Interconnect,开放系统互连参考模型)是由 ISO(国际标准化组织)定义的,它是个灵活的.稳健的和可互操作的模型,并不是协议,常用来分 ...
- 第六章 XaaS和IT服务标准
从云计算(Cloud Computing)谈起 云计算是一种按使用量付费的模式,这种模式提供可用的.便捷的.按需的网络访问,进入可配置的计算资源共享池(资源包括网络,服务器,存储,应用软件,服务),这 ...
- STM32的ADC精度提高方法
1.精度稳定低一点参考电压VREF稳定: 2.通过设置不同的ADC时钟 和 采样周期 来确定出最适合自己系统的参数: 3.测试思路: 在同样SMPx下,设定不同的时钟得到不同采样时间值: 在同样时钟下 ...
- 常用数据库连接池配置及使用(Day_11)
世上没有从天而降的英雄,只有挺身而出的凡人. --致敬,那些在疫情中为我们挺身而出的人. 运行环境 JDK8 + IntelliJ IDEA 2018.3 优点: 使用连接池的最主要的优点是性能.创 ...
- 大数据学习之路——环境配置(2)——mysql 在linux 系统上安装配置
1.安装参考网址: https://blog.csdn.net/IronWring_Fly/article/details/103637801 设置新秘密: mysqladmin -u root ...
- uni-app 富文本解析-小程序
原文:http://www.upwqy.com/manual/info/105.html 1 引入插件 gaoyia-parse 链接:https://pan.baidu.com/s/1UusfXxH ...
- JNDI注入和JNDI注入Bypass
之前分析了fastjson,jackson,都依赖于JDNI注入,即LDAP/RMI等伪协议 JNDI RMI基础和fastjson低版本的分析:https://www.cnblogs.com/pia ...