【专题】概率期望DP
11.22:保持更新状态:主要发一些相关的题目和个人理解
(P.S.如果觉得简单,可以直接看后面的题目)
upd 11.30 更完了
【NO.1】
一道比较坑的题目,多给了一个没用的条件...其实就是利用线性关系,取一个平均值就OK了。
把最优情况和最差情况算出来,取一个算数平均值算出期望就OK了,应该是最简单的一道题了,关键是要想得到
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
inline int read(){
char chr=getchar(); int f=,ans=;
while(!isdigit(chr)) {if(chr=='-') f=-;chr=getchar();}
while(isdigit(chr)) {ans=(ans<<)+(ans<<);ans+=chr-'';chr=getchar();}
return ans*f;
}
void write(int x){
if(x<) putchar('-'),x=-x;
if(x>) write(x/);
putchar(x%+'');
}
int n,d,p,i=;
double ans=;
int main(){
while(n=read(),d=read(),n||d){
++i;ans=;int k=;
while(n--){
int x=read(),y=read(),z=read();
k+=y;
ans+=2.0*y/z;
}ans+=d-k;
printf("Case %d: %.3lf\n\n",i,ans);
}
return ;
}
【NO.2】
SP1026 FAVDICE - Favorite Dice
其实这是一道赠券收集问题,这个看懂了之后,其实就很简单了
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
inline int read(){
char chr=getchar(); int f=,ans=;
while(!isdigit(chr)) {if(chr=='-') f=-;chr=getchar();}
while(isdigit(chr)) {ans=(ans<<)+(ans<<);ans+=chr-'';chr=getchar();}
return ans*f;
}
void write(int x){
if(x<) putchar('-'),x=-x;
if(x>) write(x/);
putchar(x%+'');
}
int n;
int main(){
n=read();
while(n--){
int x=read();
double ans=;
for(int i=;i<=x;i++){
ans+=x*1.0/(x-i+);
}
printf("%.2lf\n",ans);
}
return ;
}
中间小结:我们发现一个特性,代码很短,然而需要一定脑回路,想通了肯能5min就解决了,否则可能会想的很复杂(比如有一次码一百多行,后来发现可以O(1)时间一行直接输出...)
upd:11.26
【NO.3】
KIDS AND PRIZES
P.S. 额...这道题找不到来源,具体是SGU495,但是SGU消失了,Vjudge又不能提交,如果有读者知道怎么提交的话,可以在下面回复一下,谢谢
【题目描述】
n个盒子里装有礼物,m个人随机选择礼物,选完之后空盒子放回
问选中的礼物数的期望。
【思路】
有log(m)的做法(快速幂),在这里先介绍O(m)的做法
令dp[i]表示第i个人去箱子时的得到礼物的概率,那么有方程:
dp[1]=1,dp[i(i>1)]=dp[i-1]*(1-dp[i-1])+dp[i-1]*(dp[i-1]-1.0/n);
关于优化:
对上式进行化简,则有
dp[i]=dp[i-1]*(1-1.0/n)
不难发现1.0/n是一个常数 然后用数列的知识一顿瞎搞->dp[n]=(1-1.0/n)^m-1;
ans=∑dp[i]=n-n*((n-1)/n)^m
然后快速幂就好了
下面代码是O(m)的
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
inline int read(){
char chr=getchar(); int f=,ans=;
while(!isdigit(chr)) {if(chr=='-') f=-;chr=getchar();}
while(isdigit(chr)) {ans=(ans<<)+(ans<<);ans+=chr-'';chr=getchar();}
return ans*f;
}
void write(int x){
if(x<) putchar('-'),x=-x;
if(x>) write(x/);
putchar(x%+'');
}
int n,m;
double dp[],ans;
int main(){
n=read(),m=read();
dp[]=;
for(int i=;i<=m;i++)
dp[i]=dp[i-]*(-dp[i-])+dp[i-]*(dp[i-]-1.0/n),ans+=dp[i];
printf("%.5lf",ans+);
return ;
} 啦啦啦~~
感觉有点写不下去了...难受,关键是找不到一些题目...
【NO.4】
ZOJ3640 help me escape
题目描述
英语不太好,翻译不来,用机翻吧...这里就不给出了(懒..)
【思路】
记忆化搜索是个好东西,其实用记忆化搜索做这种题有时候更方便呢...
如果i>c[j] dp[i]+=(int)(p*c[j]*c[j])/n;
如果i<=c[j] dp[i]+=(dfs(i+c[j])+1)/n;
P.S.注意向下取整!!!
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
inline double read(){
char chr=getchar(); int f=,ans=;
while(!isdigit(chr)) {if(chr=='-') f=-;chr=getchar();}
while(isdigit(chr)) {ans=(ans<<)+(ans<<);ans+=chr-'';chr=getchar();}
return ans*f*1.0;
}
void write(int x){
if(x<) putchar('-'),x=-x;
if(x>) write(x/);
putchar(x%+'');
}
int n,m;
double dp[];
int a[],b[];
const double t=(sqrt(5.0)+1.0)/2.0;
double dfs(int sum){
if(dp[sum]>) return dp[sum];
for(int i=;i<=n;i++){
if(sum>a[i])
dp[sum]+=(double)b[i]/n;
else dp[sum]+=(dfs(sum+a[i])+1.0)/n;
}
return dp[sum];
}
int main(){
while(~scanf("%d%d",&n,&m)){
memset(dp,,sizeof(dp));
for(int i=;i<=n;i++)cin>>a[i],b[i]=a[i]*a[i]*t;
double ans=dfs(m);
printf("%.3lf\n",ans);
}
return ;
}
后面的题目会偏难一点噢.
upd:11.29
好吧,其实也不是很难。。。暴力枚举状态然后转移就好了
前面的题目看懂的话,这道题可以直接上代码了
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
inline int read(){
char chr=getchar(); int f=,ans=;
while(!isdigit(chr)) {if(chr=='-') f=-;chr=getchar();}
while(isdigit(chr)) {ans=(ans<<)+(ans<<);ans+=chr-'';chr=getchar();}
return ans*f;
}
void write(int x){
if(x<) putchar('-'),x=-x;
if(x>) write(x/);
putchar(x%+'');
}
double f[][][][];
int T,n,a1,a2,a3;
double solve(){
double ans=;
f[][a1][a2][a3]=;
for(int i=;i<n;i++)
for(int a=;a<=;a++)
for(int b=;b<=;b++)
for(int c=;c<=;c++){
if(a+b+c>) continue;
if(a>)f[i+][a-][b][c]+=(double)f[i][a][b][c]*(double)a/(double)(a+b+c+);
if(b>&&a+b+c==)f[i+][a+][b-][c]+=f[i][a][b][c]*(double)b/(double)(a+b+c+);
if(b>&&a+b+c<) f[i+][a+][b-][c+]+=f[i][a][b][c]*(double)b/(double)(a+b+c+);
if(c>&&a+b+c==) f[i+][a][b+][c-]+=f[i][a][b][c]*(double)c/(double)(a+b+c+);
if(c>&&a+b+c<) f[i+][a][b+][c]+=f[i][a][b][c]*(double)c/(double)(a+b+c+);
f[i+][a][b][c]+=f[i][a][b][c]/(double)(a+b+c+);
ans+=f[i][a][b][c]/(double)(a+b+c+);
}printf("%.2lf\n",ans);
} int main(){
T=read();
while(T--){memset(f,,sizeof(f));
n=read(),a1=read(),a2=read(),a3=read();solve();
}
return ;
}
最后一道
刷表法就好了,有个技巧就是可以先排序一下,然后就能保证所有背包先被处理(因为与顺序无关,上面的“依次”是骗人的)
f[i][j][k] 表示第i个挑战,赢了j次,背包容量为k,还是暴力枚举状态枚举
具体可以见代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
inline int read(){
char chr=getchar(); int f=,ans=;
while(!isdigit(chr)) {if(chr=='-') f=-;chr=getchar();}
while(isdigit(chr)) {ans=(ans<<)+(ans<<);ans+=chr-'';chr=getchar();}
return ans*f;
}
void write(int x){
if(x<) putchar('-'),x=-x;
if(x>) write(x/);
putchar(x%+'');
}
int n,l,k;
struct P{double p;int a;}a[];//概率 属性
double f[][][];
bool cmp(const P &x,const P &b){return x.a>b.a;}
int main(){
n=read(),l=read(),k=read();
for(int i=;i<=n;i++) cin>>a[i].p,a[i].p/=100.0;
for(int i=;i<=n;i++) cin>>a[i].a;
sort(a+,a+n+,cmp);
f[][][min(,k)]=;
for(int i=;i<n;i++)
for(int j=;j<=i;j++)
for(int k=;k<=n;k++){
f[i+][j][k]+=f[i][j][k]*(1.0-a[i+].p);//失败
int v=k+a[i+].a;
if(v<) continue;v=min(n,v);
f[i+][j+][v]+=f[i][j][k]*a[i+].p;//成功
}
double ans=;
for(int i=l;i<=n;i++)
for(int j=;j<=n;j++)
ans+=f[n][i][j];
printf("%.6lf",ans);
return ;
}
【专题】概率期望DP的更多相关文章
- 【BZOJ-1419】Red is good 概率期望DP
1419: Red is good Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 660 Solved: 257[Submit][Status][Di ...
- 【bzoj4832】[Lydsy2017年4月月赛]抵制克苏恩 概率期望dp
题目描述 你分别有a.b.c个血量为1.2.3的奴隶主,假设英雄血量无限,问:如果对面下出一个K点攻击力的克苏恩,你的英雄期望会受到到多少伤害. 输入 输入包含多局游戏. 第一行包含一个整数 T (T ...
- 【loj6191】「美团 CodeM 复赛」配对游戏 概率期望dp
题目描述 n次向一个栈中加入0或1中随机1个,如果一次加入0时栈顶元素为1,则将这两个元素弹栈.问最终栈中元素个数的期望是多少. 输入 一行一个正整数 n . 输出 一行一个实数,表示期望剩下的人数, ...
- Codeforces - 1264C - Beautiful Mirrors with queries - 概率期望dp
一道挺难的概率期望dp,花了很长时间才学会div2的E怎么做,但这道题是另一种设法. https://codeforces.com/contest/1264/problem/C 要设为 \(dp_i\ ...
- 概率期望dp
对于概率dp,我一直都弄得不是特别明白,虽然以前也有为了考试去突击过,但是终究还是掌握得不是很好,所以决定再去学习一遍,把重要的东西记录下来. 1.hdu4405 Description 在一个 \( ...
- Codeforces 908 D.New Year and Arbitrary Arrangement (概率&期望DP)
题目链接:New Year and Arbitrary Arrangement 题意: 有一个ab字符串,初始为空. 用Pa/(Pa+Pb)的概率在末尾添加字母a,有 Pb/(Pa+Pb)的概率在末尾 ...
- [BZOJ4832]抵制克苏恩(概率期望DP)
方法一:倒推,最常规的期望DP.f[i][a][b][c]表示还要再攻击k次,目前三种随从个数分别为a,b,c的期望攻击英雄次数,直接转移即可. #include<cstdio> #inc ...
- LightOJ 1030 Discovering Gold (概率/期望DP)
题目链接:LightOJ - 1030 Description You are in a cave, a long cave! The cave can be represented by a \(1 ...
- 【POJ 2096】Collecting Bugs 概率期望dp
题意 有s个系统,n种bug,小明每天找出一个bug,可能是任意一个系统的,可能是任意一种bug,即是某一系统的bug概率是1/s,是某一种bug概率是1/n. 求他找到s个系统的bug,n种bug, ...
随机推荐
- javascript模块化编程(一)(http://www.ruanyifeng.com/blog/2012/10/javascript_module.html)
Javascript模块化编程(一):模块的写法 随着网站逐渐变成"互联网应用程序",嵌入网页的Javascript代码越来越庞大,越来越复杂. 网页越来越像桌面程序,需要一个 ...
- apache配置多域名二级域名
nginx配置多域名泛解析的看这个链接:https://www.cnblogs.com/Crazy-Liu/p/10879740.html 下面直接来操作: [root@localhost ~]# f ...
- Linux如何查看端口(转)
Linux如何查看端口 1.lsof -i:端口号 用于查看某一端口的占用情况,比如查看8000端口使用情况,lsof -i:8000 # lsof -i:8000 COMMAND PID USER ...
- 所有对象的父类(java.lang.Object)
一.介绍 Object类是类层次结构的根源,每一个类都存在一个父类为Object类.所有的对象,包括数组,都实现了 Object 类的方法. 二.对象初始化 这里使用了静态代码块进行Object类的初 ...
- Capture the Flag ZOJ - 3879(模拟题)
In computer security, Capture the Flag (CTF) is a computer security competition. CTF contests are us ...
- char如何储存3个字节或者4个字节
1.char字符存储的是Unicode编码的代码点,也就是存储的是U+FF00这样的数值,然而我们在调试或者输出到输出流的时候,是JVM或者开发工具按照代码点对应的编码字符输出的. 2. 所以虽然UT ...
- 水图(牛客练习赛(DFS搜索))
题意: 小w不会离散数学,所以她van的图论游戏是送分的 小w有一张n个点n-1条边的无向联通图,每个点编号为1~n,每条边都有一个长度小w现在在点x上她想知道从点x出发经过每个点至少一次,最少需要走 ...
- TensorFlow 学习笔记(2)----placeholder的使用
此系列将会每日持续更新,欢迎关注 在TensorFlow中输入值的方式是通过placeholder来实现 例如:做两个数的乘法时,是先准备好两个place, 再将输出值定义成两数的乘法 最后利用ses ...
- 第三节:Web爬虫之BeautifulSoup解析库
Beautiful Soup官方说明: Beautiful Soup提供一些简单的.python式的函数用来处理导航.搜索.修改分析树等功能.它是一个工具箱,通过解析文档为用户提供需要抓取的数据,因为 ...
- sql 语句实现可用户名、邮箱、手机号登录系统
select top 1 nid from Users where (userName collate Chinese_PRC_CS_AS=@userName or mobile collate Ch ...