期望DP入门

news2024/11/15 15:36:15

期望DP一般步骤:

1.模拟过程,找出线性性质,作为阶段(这本质上也是线性DP)

2.涉及DP状态

原则:

体现线性性质

体现边权

根据对期望有无贡献来设计状态

一般在状态设计时需要倒着设计

3.转移

根据边权转移

分为对期望贡献的区别来分开计算贡献

不同情况的概率贡献不一样,因此期望贡献也不一样,因此需要分开考虑

考虑权值时可以递归地考虑

1.

题意:

 

思路:

设一直选直到1号球被选中的期望选择次数是E

可以列方程:

E=1/n+(1-1/n)*(E+1)

求出E=n

2.

 

 思路:

首先概率是一定的

在选的过程中,如果选到了1-K号的某个没被选过的球,剩下就选K-1个,因此线性性质就体现在 剩下还要选多少球 中

所以这个可以记成一个状态

所以最终设出来的状态只有一维:

设dp[i]为还剩下i个球选的选择次数的期望

然后考虑转移

选择的决策可以分为,选对选择次数有贡献的,和选对选择次数没有贡献的

选没被选过且编号在1-K的,就是对次数有贡献的,否则就是没有贡献的

前者的期望贡献:dp[i]+=k/n*(dp[i-1]+1),边权为1

后者的期望贡献:dp[i]+=(1-k/n)*(dp[i-1]+1),边权为1

Code:

#include <bits/stdc++.h>

#define int long long

using namespace std;

const int mxn=1e6+10;
const int mxe=1e3+10;
const int mod=1e9+7;

int N,Q,K;
int E[mxn];

int ksm(int a,int b,int mod){
	int res=1;
	while(b){
		if(b&1) res=(res*a)%mod;
		a=(a*a)%mod;
		b>>=1;
	}
	return res;
}
void solve(){
	cin>>N>>Q;
	E[1]=N;
	for(int i=2;i<=N;i++) E[i]=(E[i-1]+N*ksm(i,mod-2,mod)%mod)%mod;
	while(Q--){
		cin>>K;
		cout<<E[K]%mod<<'\n';
	}
}
signed main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int __=1;//cin>>__;
    while(__--)solve();return 0;
}

3.

题意:

 

 思路:

首先看它的决策是什么时,对期望产生贡献

当它选红色且没有被选过的小球时,对期望有贡献,否则就是没有贡献

设计的状态需要体现期望贡献

红色:m

没有被选过:用k表示还需要选多少球,这也体现了线性性质

因为已经选过的红色小球对期望没有贡献,因此可以把选过的红色小球去掉

因此设dp[k][m]为还剩下m个红色小球,且还需要选k个不同编号的红色小球的选择次数的期望

转移:

对期望有贡献的部分:m/n*(dp[k-1][m-1]+1)

对期望无贡献的部分:(1-m/n)*(dp[k][m]+1)

然后解个方程就出来了

dp[k][m]=dp[k-1][m-1]+n/m

Code:

#include <bits/stdc++.h>

#define int long long

using namespace std;

const int mxn=1e2+10;
const int mxe=1e3+10;
const int mod=1e9+7;

int N,M,Q,K;
int E[mxn][mxn];

int ksm(int a,int b,int mod){
	int res=1;
	while(b){
		if(b&1) res=(res*a)%mod;
		a=(a*a)%mod;
		b>>=1;
	}
	return res;
}
void solve(){
	while(cin>>N>>M>>Q){
		E[1][1]=N;
		for(int i=1;i<=M;i++){
			for(int j=1;j<=i;j++){
				E[i][j]=(E[i-1][j-1]+N*ksm(i,mod-2,mod)%mod)%mod;
			}
		}
		while(Q--){
			cin>>K;
			cout<<E[M][K]%mod<<'\n';
		}
	}
}
signed main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int __=1;//cin>>__;
    while(__--)solve();return 0;
}

4.

题意:

思路:

分为尝试成功和尝试失败两部分进行转移

Code:

#include <bits/stdc++.h>
 
#define int long long
 
using namespace std;
 
const int mxn=1e7+10;
const int mxe=1e3+10;
const int mod=1e9+7;
 
int N;
int a[mxn],Fac[mxn];
 
int ksm(int a,int b,int mod){
    int res=1ll;
    while(b){
        if(b&1) res=(res*a)%mod;
        a=(a*a)%mod;
        b>>=1;
    }
    return res%mod;
}
void F_init(){
    Fac[0]=1;
    for(int i=1;i<mxn;i++) Fac[i]=(Fac[i-1]*i)%mod;
}
void solve(){
    int sum=0;
    for(int i=1;i<=10;i++){
        cin>>a[i];
        sum+=a[i];
    }
    int ans=Fac[sum];
    for(int i=1;i<=10;i++) ans=ans*ksm(Fac[a[i]],mod-2,mod)%mod;
    cout<<ans<<'\n';
}
signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int __=1;//cin>>__;
    F_init();
    while(__--)solve();return 0;
}

5.

题意:

思路:

因为计算期望时需要计算概率,计算概率需要n和s这两个参数

因此在设计状态时需要用这两个参数

设dp[n][s]为,已经发现了n种bug,s个子系统的天数期望

然后可以分为4种情况来转移,每种情况的概率贡献不一样 

Code:

#include <bits/stdc++.h>
 
#define int long long
 
using namespace std;
 
const int mxn=1e3+10;
const int mxe=1e6+10;
const int mod=1e9+7;
const int Inf=1e18;
 
int N,S;
double dp[mxn][mxn];
 
void solve(){
    cin>>N>>S;
    dp[N][S]=0;
    for(int i=N;i>=0;i--){
        for(int j=S;j>=0;j--){
            if(i==N&&j==S) continue;
            dp[i][j]=(N*S+(N-i)*j*dp[i+1][j]+i*(S-j)*dp[i][j+1]+(N-i)*(S-j)*dp[i+1][j+1])/(N*S-i*j);
        }
    }
    cout<<fixed<<setprecision(4)<<dp[0][0]<<'\n';
}
signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int __=1;//cin>>__;
    while(__--)solve();return 0;
}

6.

思路:

同样的,也是设期望时间,然后列方程(转移)

设逃离迷宫的期望时间为E

 Code:

#include <bits/stdc++.h>
 
using namespace std;
 
const int mxn=1e2+10;
const int mxe=1e3+10;
 
int N,idx=0;
int x[mxn];
 
void solve(){
    cin>>N;
    for(int i=1;i<=N;i++) cin>>x[i];
    int s1=0,s2=0,cnt=0;
    for(int i=1;i<=N;i++){
        if(x[i]<0){
            cnt++;
            s2+=(-x[i]);
        }else{
            s1+=x[i];
        }
    }
    int d1=(s1+s2);
    int d2=(N-cnt);
    int d=__gcd(d1,d2);
    d1/=d,d2/=d;
    if(cnt==N) cout<<"Case "<<++idx<<": inf"<<'\n';
    else cout<<"Case "<<++idx<<": "<<d1<<"/"<<d2<<'\n';
}
int main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int __=1;cin>>__;
    while(__--)solve();return 0;
}

7.

题意:

 

思路:

这个的线性性质很明显

设dp[i]为从位置 i 到位置 N 得到金子的价值的期望

它有min(6,N-i)种决策,只要不超过N就行

Code:

#include <bits/stdc++.h>
 
#define int long long
 
using namespace std;
 
const int mxn=1e2+10;
const int mxe=1e6+10;
const int mod=1e9+7;
const int Inf=1e18;
 
int tot=0;
int N;
int a[mxn];
double dp[mxn];
//从位置i到位置N的期望价值
 
void solve(){
    cin>>N;
    for(int i=0;i<=N;i++) dp[i]=0.0;
    for(int i=1;i<=N;i++) cin>>a[i];
    dp[N]=0.0;
    for(int i=N-1;i>=1;i--){
        for(int k=1;k<=6;k++){
            double p=1.0/min((N-i)*1.0,6.0);
            dp[i]+=(dp[i+k]+1.0*a[i+k])*p;
        }
    }
    cout<<fixed<<setprecision(8)<<"Case "<<++tot<<":"<<" "<<dp[1]+a[1]<<'\n';
}
signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int __=1;cin>>__;
    while(__--)solve();return 0;
}

 

8.

 

思路:

Code:

#include <bits/stdc++.h>
 
#define int long long
 
using namespace std;
 
const int mxn=1e5+10;
const int mxe=1e5+10;
const int mod=1e9+7;
const int Inf=1e18;
 
struct ty{
    int to,next;
}edge[mxe<<2];
 
int N,tot=0;
int u,v;
int head[mxn];
double ans=0;
 
void add(int u,int v){
    edge[tot].to=v;
    edge[tot].next=head[u];
    head[u]=tot++;
}
void G_init(){
    tot=0;
    for(int i=0;i<=N;i++){
        head[i]=-1;
    }
}
void dfs(int u,int fa,int dep){
    ans+=1.0/(1.0*dep);
    for(int i=head[u];~i;i=edge[i].next){
        if(edge[i].to==fa) continue;
        dfs(edge[i].to,u,dep+1);
    }
}
void solve(){
    cin>>N;
    G_init();
    for(int i=1;i<=N-1;i++){
        cin>>u>>v;
        add(u,v);
        add(v,u);
    }
    dfs(1,1,1);
    cout<<fixed<<setprecision(8)<<ans<<'\n';
}
signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int __=1;//cin>>__;
    while(__--)solve();return 0;
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/732123.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何将自定义字体添加到 iOS 应用程序(SwiftUI + 得意黑)

1. 工具 Xcode Version 14.3 (14E222b)SwiftUI得意黑 Smiley Sans 2. Download https://github.com/atelier-anchor/smiley-sans/releases 3. Add Files to xxx 4. Add Test Code Text("Less is more. 朱洪苇 123").font(.custom("SmileySans-Oblique",…

【电子量产工具】4. UI系统

文章目录 前言一、UI界面分析二、结构体描述按钮三、按钮初始化四、默认绘制按键事件函数五、默认按下按键事件函数六、测试程序实验效果总结 前言 最近看了 电子量产工具 这个项目&#xff0c;本专栏是对该项目的一个总结。 一、UI界面分析 UI 是用户界面&#xff08;User In…

GEE:提取地区 NDVI/LST/RVI 并进行时间序列线性插值和SG滤波

作者&#xff1a;CSDN _养乐多_ 本文将介绍使用Landsat数据集&#xff0c;构建时间序列&#xff0c;并使用线性插值算法填补缺失数据&#xff0c;或者去云空洞&#xff0c;并进一步对完整的时间序列数据进行SG滤波处理。 文章目录 一、代码二、代码链接三、需要请私聊 一、代…

OPCUA 的历史数据库/聚合服务器的实现细节

进入了AI 大数据时代&#xff0c;无论是工业自动化系统&#xff0c;还是物联网系统&#xff0c;对大数据的采集&#xff0c;存储和分析都十分重要。大数据被称为工业的石油&#xff0c;未来制造业的持续改善离不开大数据。 传统的应用中&#xff0c;历史数据的存储是特定的数据…

官方外设库SDA安装和验证

第一种方法 1.打开mobaxterm&#xff0c;通过windows浏览器打开https://github.com/orangepi-xunlong/wiringOP下载压缩包&#xff0c;点击上传外设库的压缩包 2.输入命令 unzip 解压 3.输入命令 sudo ./build 安装工具包 4.验证安装完毕用 输入gpio readall 显示下面图片 第二…

数据分析实战(基础篇):从数据探索到模型解释

前言 本文着重介绍数据分析实战的基础知识和技巧&#xff0c;探索从数据探索到建模再到模型解释的完整过程内容包含数据探索、模型建立、调参技巧、SHAP模型解释数据来源于kaggle平台&#xff0c;crab age prediction数据集&#xff0c;数据详情 数据说明 数据背景 螃蟹味道…

【性能设计篇】聊聊异步处理

在性能设计的时候&#xff0c;其实主要的三板斧就是数据库(读写分离、分库分表)&#xff0c;缓存&#xff08;提升读性能&#xff09;&#xff0c;异步处理&#xff08;提升写性能&#xff09;以及相关的秒杀设计以及边缘设计等。 本篇主要介绍异步处理的哪些事&#xff0c;我们…

6.2.1 网络基本服务---域名解析系统DNS

6.2.1 网络基本服务—域名解析系统DNS 因特网是需要提供一些最基本的服务的&#xff0c;今天我们就来讨论一下这些基本的服务。 域名系统&#xff08;DNS&#xff09;远程登录&#xff08;Telnet&#xff09;文件传输协议&#xff08;FTP&#xff09;动态主机配置协议&#x…

Day47

思维导图 练习 实现登录框中&#xff0c;当登录成功时&#xff0c;关闭登录界面&#xff0c;并跳转到其他界面 second.h #ifndef SECOND_H #define SECOND_H#include <QWidget>namespace Ui { class Second; }class Second : public QWidget {Q_OBJECTpublic:explicit …

Matlab绘图时的几个小技巧(修改刻度线长度、添加/去掉右边和上面的轴与刻度线、出图时去掉旁边的空白部分)

set(gca,TickLength,[0.005,0.035]); %修改坐标轴刻度线的长度 box on; %开启右面和上面的坐标轴 box off;%关闭右面和上面的坐标轴 set(gca, LooseInset, [0,0,0,0]);%删除掉图旁边多余的空白部分首先随便出一张图 我想让刻度线更长或更短一些&#xff1a; 我想让右侧和上面…

OpenCV的安装与配置指南(Windows环境,Python语言)

OpenCV 的安装与配置指南&#xff08;Windows环境&#xff0c;Python语言&#xff09; 导语一、安装 Python 二、安装 OpenCV 库三、配置 OpenCV 环境变量四、验证 OpenCV 安装总结 导语 OpenCV 是一个功能强大的计算机视觉库&#xff0c;广泛应用于图像处理和计算机视觉领域。…

第十二章 elk

1、ELK可以帮助我们解决哪些问题 日志分布在多台不同的服务器上,业务一旦出现故障,需要一台台查看日志 单个日志文件巨大,无法使用常用的文本工具分析,检索困难; 2、架构设计分析 Filebeat和Logstash ELK架构中使用Logstash收集、解析日志,但是Logstash对内存、cpu、i…

MySQL入门必备:Linux中部署MySQL环境的四种方式详解

目录 一、仓库安装 二、本地安装 三、Docker中安装 四、源码安装 一、仓库安装 首先需要下载mysql软件包&#xff1a; 1、进入MySQL官网 2、进入MySQL社区版下载 3、使用yum方式下载MySQL 4、下载对应版本的软件包 5、这里可以不登录直接下载软件包 6、复制下载链接 7、然…

Perfetto详细解析

一、Perfetto基础 1、Perfetto介绍 Perfetto 是一个生产级的开源堆栈&#xff0c;用于提高性能 仪器和痕量分析。与 Systrace 不同&#xff0c;它提供数据源超集&#xff0c;可以用 protobuf 编码的二进制流形式记录任意长度的跟踪记录。可以将Perfetto理解为systrace的升级版…

Python——爬虫入门

爬虫的流程 第一步:获取网页内容 浏览器访问网页时也是一样&#xff0c;都是先发个请求获取网页内容&#xff0c;但是浏览器多了个渲染的步骤。 程序获取的内容都是网页源代码 第二步:解析网页内容 第三步:储存或分析数据 要做数据集就存起来&#xff0c;要做数据分析就形…

【Matlab】GRNN神经网络遗传算法(GRNN-GA)函数极值寻优——非线性函数求极值

上一篇博客介绍了BP神经网络遗传算法(BP-GA)函数极值寻优——非线性函数求极值&#xff0c;神经网络用的是BP神经网络&#xff0c;本篇博客将BP神经网络替换成GRNN神经网络&#xff0c;希望能帮助大家快速入门GRNN网络。 1.背景条件 要求&#xff1a;对于未知模型&#xff08;…

scratch 角色追踪

scratch 角色追踪 本程序中一个角色移动到随机位置和方向后向前移动&#xff0c;碰到边缘反弹&#xff1b;另一个角色跟随前一个角色&#xff0c;两个角色接触后前者重新取随机位置。 程序内容如下

Linux——进程信号详解

目录 一.进程信号的理解 1.1定义&#xff1a; 1.2举例&#xff1a; 1.3总结&#xff1a; 二.进程信号地使用&#xff1a; 2.1信号种类&#xff1a; 2.2而操作系统向进程发送信号地方式有四种&#xff1a; 2.2.1以键盘的方式向进程发送信号 接下来介绍一个系统调用函数sign…

【项目】C++实现高并发内存池

文章目录 一、项目介绍1.1 项目原型1.2 池化技术1.3 内存池主要解决的问题1.4 malloc理解 二、定长内存池实现三、高并发内存池的三层申请内存框架设计3.1 thread cache层的设计3.1.1 thread cache整体框架3.1.2 哈希桶映射对齐规则3.1.3 thread cacheTLS无锁访问 3.2 central …

【剑指offer】10. 矩阵中的路径(java)

文章目录 矩阵中的路径描述示例1示例2思路完整代码 矩阵中的路径 描述 请设计一个函数&#xff0c;用来判断在一个n乘m的矩阵中是否存在一条包含某长度为len的字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始&#xff0c;每一步可以在矩阵中向左&#xff0c;向右&…