当前位置: 首页 > news >正文

[NOI2005]聪聪与可可(期望)

题意

OI版猫和老鼠

给定一个有n个点的图(\(n\leq 1000\)),在s点有一只猫,t点有一只jerry,每一单位时间猫先走:沿着到jerry的路径中的最短路走一步,如果同时存在多条最短路则选择走一步后序号更小的一条,另外,如果这一步没有走到jerry所在的点,猫会再走一步(砸瓦鲁多);jerry后走,可等概率的向直接与自己所在的点走一步或者选择不动(即各个点概率均为1/(入度+1)),求猫抓住jerry的期望时间

思路

在做期望dp之前,要先解决一个问题:猫的走路姿态问题

关于猫走法的一些考察

这道题中猫的走法看似难以捉摸,其实可以看出,对于确定的( s ,t ),猫的着陆点也是确定的,所以是可以预处理出来的

首先,最短路这一个限制说明了是要对每一个点跑一次spfa(2005年spfa尚未狗带),求出dis数组之后,我们还要求出对应的nxt数组,表示从s向t跳一步之后到达的位置(具体的,如何判断一个点是否为s到t最短路上的走一步的点,只要满足dis[s][t]-1==dis[v][t],那么v就是这样的一个点)

期望dp

预处理上面的nxt数组之后,这道题就是一道比较简单的期望dp了

按照套路,设f[ i ] [ j ]表示猫在i,jerry在j的总期望,ans=f[ s ] [ t ]

初始状态:

s==t时,f[ s ] [ t ]=0
t==nxt[ fir ] [ t ] or t==nxt[ sec ][ t ]时,f [ s ] [ t ]=1
其他情况下,f[ s ] [ t ] =sigma(f[ sec ] [ t ] / ( rd + 1 ) )+1

其中,fir=nxt[ s ] [ t ],即从s向t走一步,同样,sec=nxt[ fir ] [ t ],即从s向t走两步

代码采用记忆化搜索完成dp

Code:

#include<bits/stdc++.h>
#define N 1005
#define INF 1000000000
using namespace std;
typedef long double ld;
int n,m,s,t;
int rd[N],nxt[N][N],dis[N][N];
ld f[N][N];
bool vis[N][N];
struct Edge
{
    int next,to;
}edge[N<<2];int head[N],cnt=1;
void add_edge(int from,int to)
{
    edge[++cnt].next=head[from];
    edge[cnt].to=to;
    head[from]=cnt;
}
template <class T>
void read(T &x)
{
    char c;int sign=1;
    while((c=getchar())>'9'||c<'0') if(c=='-') sign=-1; x=c-48;
    while((c=getchar())>='0'&&c<='9') x=(x<<1)+(x<<3)+c-48; x*=sign; 
}
void spfa(int *dis,int s)
{
    bool exist[N]={0};
    queue<int> q;
    q.push(s);dis[s]=0;exist[s]=1;
    while(!q.empty())
    {
        int u=q.front();q.pop();exist[u]=0;
        for(int i=head[u];i;i=edge[i].next)
        {
            int v=edge[i].to;
            if(dis[v]>dis[u]+1)
            {
                dis[v]=dis[u]+1;
                if(!exist[v]) {exist[v]=1; q.push(v);}
            }
        }
    }
    
}
ld dfs(int s,int t)
{
    if(vis[s][t]) return f[s][t];
    if(s==t) return f[s][t]=0;
    int fir=nxt[s][t];
    int sec=nxt[fir][t];
    f[s][t]=1;
    if(fir==t||sec==t) return 1;
    for(int i=head[t];i;i=edge[i].next)
    {
        int v=edge[i].to;
        f[s][t]+=dfs(sec,v)/(rd[t]+1);
    }
    f[s][t]+=dfs(sec,t)/(rd[t]+1);
    vis[s][t]=1;
    return f[s][t];
}
int main()
{
    read(n);read(m);
    read(s);read(t);
    for(int i=1;i<=m;++i)
    {
        int x,y;
        read(x);read(y);
        add_edge(x,y);
        add_edge(y,x);
        rd[x]++;rd[y]++;
    }
    for(int i=1;i<=n;++i)
    for(int j=1;j<=n;++j) dis[i][j]=nxt[i][j]=INF;
    for(int i=1;i<=n;++i) spfa(dis[i],i);
    for(int i=1;i<=n;++i)
    for(int j=1;j<=n;++j)
    for(int h=head[i];h;h=edge[h].next)
    {
        int v=edge[h].to;
        if(dis[i][j]-1==dis[v][j]) nxt[i][j]=min(nxt[i][j],v);
    }
    printf("%.3Lf",dfs(s,t));
    return 0;
}

这道题分点讨论比较多,只要把问题拆成许多小问题,就会发现是许多小模板拼凑成的,是一道期望dp入门好题

转载于:https://www.cnblogs.com/Chtholly/p/11210160.html

相关文章:

  • span底部显示border一半
  • Django之ORM多表操作
  • Dilated/Atrous conv 空洞卷积/多孔卷积
  • PHP 用户登录与退出
  • Java之线程池深度剖析
  • POCO浅探
  • Dataset+TableAdapter _.net最终数据访问类出现? 我的心血显然被藐视了
  • Scrum实施日记 - 我可以问问题吗?
  • Design Patterns
  • 手机端雅安地震寻人整合项目
  • 香港身份证
  • UDDI(一)
  • 浅谈 XSS CSRF(转)
  • ansible笔记(2):管理清单配置详解
  • VS2015 Web应用程序发布
  • JavaScript-如何实现克隆(clone)函数
  • 【从零开始安装kubernetes-1.7.3】2.flannel、docker以及Harbor的配置以及作用
  • 【前端学习】-粗谈选择器
  • 2017前端实习生面试总结
  • 77. Combinations
  • CODING 缺陷管理功能正式开始公测
  • Cookie 在前端中的实践
  • ES学习笔记(10)--ES6中的函数和数组补漏
  • GDB 调试 Mysql 实战(三)优先队列排序算法中的行记录长度统计是怎么来的(上)...
  • java B2B2C 源码多租户电子商城系统-Kafka基本使用介绍
  • javascript 总结(常用工具类的封装)
  • java第三方包学习之lombok
  • Java新版本的开发已正式进入轨道,版本号18.3
  • jdbc就是这么简单
  • JS函数式编程 数组部分风格 ES6版
  • VUE es6技巧写法(持续更新中~~~)
  • Vue小说阅读器(仿追书神器)
  • webgl (原生)基础入门指南【一】
  • 反思总结然后整装待发
  • 观察者模式实现非直接耦合
  • 基于Android乐音识别(2)
  • 开源SQL-on-Hadoop系统一览
  • 力扣(LeetCode)21
  • - 转 Ext2.0 form使用实例
  • 浅谈sql中的in与not in,exists与not exists的区别
  • 容器镜像
  • 如何在招聘中考核.NET架构师
  • 小白应该如何快速入门阿里云服务器,新手使用ECS的方法 ...
  • ​flutter 代码混淆
  • #laravel 通过手动安装依赖PHPExcel#
  • (2.2w字)前端单元测试之Jest详解篇
  • (4)事件处理——(2)在页面加载的时候执行任务(Performing tasks on page load)...
  • (9)目标检测_SSD的原理
  • (二) Windows 下 Sublime Text 3 安装离线插件 Anaconda
  • (附源码)spring boot北京冬奥会志愿者报名系统 毕业设计 150947
  • (机器学习-深度学习快速入门)第三章机器学习-第二节:机器学习模型之线性回归
  • (欧拉)openEuler系统添加网卡文件配置流程、(欧拉)openEuler系统手动配置ipv6地址流程、(欧拉)openEuler系统网络管理说明
  • (四)c52学习之旅-流水LED灯
  • (一)Mocha源码阅读: 项目结构及命令行启动
  • (转)创业家杂志:UCWEB天使第一步