CF_229E_Gift_概率DP+组合数学
CF_229E_Gift_概率DP+组合数学
题目描述:
很久很久以前,一位老人和他的妻子住在蔚蓝的海边。有一天,这位老人前去捕鱼,他捉到了一条活着的金鱼。鱼说:“噢,老渔人!我祈求你放我回到海里,这样的话我保证给你n样礼物——任何你想要的礼物!”鱼给了老人一张礼物的清单并附上了礼物的价值。清单上的一些礼物可能会有相同的名称、不同的价值,也可能会有不同的名称、相同的价值。然而,清单上不会出现名称和价值都相同的礼物。老人可以向鱼索要清单上的n个礼物。假设清单上有p样礼物价值相同,则该礼物不能被索要超过p次。老人知道,如果他索要同一个名称s次,那么金鱼会等概率地随机选择该名称下的s样礼物。老人想要满足他贪心的妻子,所以他会选择价值最高的n样礼物。此外,如果有不同的方法选择最高价值的n样礼物,他会等概率地采用其中任意一个方法。老人想知道,他能拿到n样价值最高的礼物的概率是多少。然而他不怎么擅长概率论,于是就来向你求助。
输入格式
第一行有两个整数n和m,n代表老人想要的礼物数量、m代表清单上各不相同的名称的数量。接下来有m行,第i行首先包括一个整数ki(ki> 0),代表第i个名称下礼物的数量。接着,ki个各不相同的整数cij(1<=cij<=109)是这些礼物的价格。
输出格式
输出仅一行:一个实数——老人拿到n样价值最高的礼物的概率。绝对误差不超过10-9时,输出被认为是正确的。
样例
gift1.in gift1.out
3 1
3 10 20 30 1.000000000
////////////
gift2.in gift2.out
3 2
1 40
4 10 20 30 40 0.166666667
/////////////
gift3.in gif3.out
3 2
3 1 2 3
1 1 0.666666667
首先能够发现有一些礼物是必须选的,设编号为$i$的礼物中必须选的个数为$cnt[i]$,有一些可能选的。
然后发现必须选的礼物一定是所有礼物中价值第$n$大的,记为$val[n]$,并且可能选的那些一定等于$val[n]$,并记录等于$val[n]$的礼物个数$ry$,应该选价值为$val[n]$的礼物个数$rm$。
题中又说了编号相同则价值不会相同,所以同一编号下最多只会有一个是可能选的。
可以暴力枚举那些编号是选的,然后除上组合数。最后再除以$C[ry][rm]$。
暴力复杂度指数级别,显然过不了这题,于是加上个记忆化。
设$F[i][j]$表示考虑前$i$编号的礼物,已经选了$j$个可以选的最后成功的概率。
那么有初始值$F[0][0]=1$,答案为$F[m][rm]/C[ry][rm]$。
有转移:$F[i][j]=F[i-1][j]/C[k[i]][cnt[i]]$。如果$i$编号中有可能选的,则需要额外加上$F[i-1][j-1]/C[k[i]][cnt[i]+1]$。
时间复杂度$O(nm)$
代码:
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
typedef double f3;
int n,m,k[1050],val[1050],a[1050][1050],cnt[1050],w[1050],is[1050];
f3 C[1050][1050],f[1030][1030];
inline bool cmp(int x,int y) {return x>y;}
int main() {
//freopen("gift.in","r",stdin);
//freopen("gift.out","w",stdout);
scanf("%d%d",&n,&m);
int i,j;
int tot=0;
for(i=1;i<=m;i++) {
scanf("%d",&k[i]);
for(j=1;j<=k[i];j++) {
scanf("%d",&a[i][j]);
val[++tot]=a[i][j];
}
}
int ry=0,rm=0;
sort(val+1,val+tot+1,cmp);
int v=val[n];
for(i=1;i<=m;i++) {
for(j=1;j<=k[i];j++) {
if(a[i][j]>v) cnt[i]++;
if(a[i][j]==v) {
w[++ry]=i;
is[i]=1;
}
}
}
for(i=n;i>=1;i--) {
if(val[i]==val[n]) rm++;
else break;
}
for(i=0;i<=tot;i++) C[i][0]=C[i][i]=1;
for(i=1;i<=tot;i++) {
for(j=1;j<=i;j++) {
C[i][j]=C[i-1][j]+C[i-1][j-1];
}
}
f3 tmp=C[ry][rm];
//printf("%d\n",tot);
//for(i=0;i<=ry;i++) f[0][i]=1;
f[0][0]=1;
for(i=1;i<=m;i++) {
for(j=0;j<=rm;j++) {
if(is[i]&&j) {
f[i][j]=f[i-1][j-1]/C[k[i]][cnt[i]+1];
}
f[i][j]+=f[i-1][j]/C[k[i]][cnt[i]];
//printf("%.9f\n",(double)f[i][j]);
}
}
printf("%.9f\n",f[m][rm]/tmp);
}
CF_229E_Gift_概率DP+组合数学的更多相关文章
- UVa 11021 Tribles (概率DP + 组合数学)
题意:有 k 只小鸟,每只都只能活一天,但是每只都可以生出一些新的小鸟,生出 i 个小鸟的概率是 Pi,问你 m 天所有的小鸟都死亡的概率是多少. 析:先考虑只有一只小鸟,dp[i] 表示 i 天全部 ...
- 【bzoj5004】开锁魔法II 组合数学+概率dp
题目描述 有 $n$ 个箱子,每个箱子里有且仅有一把钥匙,每个箱子有且仅有一把钥匙可以将其打开.现在随机打开 $m$ 个箱子,求能够将所有箱子打开的概率. 题解 组合数学+概率dp 题目约定了每个点的 ...
- 【整理】简单的数学期望和概率DP
数学期望 P=Σ每一种状态*对应的概率. 因为不可能枚举完所有的状态,有时也不可能枚举完,比如抛硬币,有可能一直是正面,etc.在没有接触数学期望时看到数学期望的题可能会觉得很阔怕(因为我高中就是这么 ...
- Codeforces 28C [概率DP]
/* 大连热身D题 题意: 有n个人,m个浴室每个浴室有ai个喷头,每个人等概率得选择一个浴室. 每个浴室的人都在喷头前边排队,而且每个浴室内保证大家都尽可能均匀得在喷头后边排队. 求所有浴室中最长队 ...
- HDU 4405 Aeroplane chess (概率DP)
题意:你从0开始,要跳到 n 这个位置,如果当前位置是一个飞行点,那么可以跳过去,要不然就只能掷骰子,问你要掷的次数数学期望,到达或者超过n. 析:概率DP,dp[i] 表示从 i 这个位置到达 n ...
- POJ 2096 Collecting Bugs (概率DP)
题意:给定 n 类bug,和 s 个子系统,每天可以找出一个bug,求找出 n 类型的bug,并且 s 个都至少有一个的期望是多少. 析:应该是一个很简单的概率DP,dp[i][j] 表示已经从 j ...
- POJ 2151 Check the difficulty of problems (概率DP)
题意:ACM比赛中,共M道题,T个队,pij表示第i队解出第j题的概率 ,求每队至少解出一题且冠军队至少解出N道题的概率. 析:概率DP,dp[i][j][k] 表示第 i 个队伍,前 j 个题,解出 ...
- 概率DP light oj 1030
t组数据 n块黄金 到这里就捡起来 出发点1 到n结束 点+位置>n 重掷一次 dp[i] 代表到这里的概率 dp[i]=(dp[i-1]+dp[i-2]... )/6 如果满6个的话 否则 ...
- hdu 4050 2011北京赛区网络赛K 概率dp ***
题目:给出1-n连续的方格,从0开始,每一个格子有4个状态,左右脚交替,向右跳,而且每一步的步长必须在给定的区间之内.当跳出n个格子或者没有格子可以跳的时候就结束了,求出游戏的期望步数 0:表示不能到 ...
随机推荐
- Next Permutation 下一个排列
Implement next permutation, which rearranges numbers into the lexicographically next greater permuta ...
- 初识Java——循环语句
循环语句就是在一定条件下反复执行某一个操作.具体有三种方法实现: 1while循环语句 while语句也称作条件判断语句,它的循环方式为利用一个条件来控制是否要反复执行.语法如下: while(条件语 ...
- Spring定时任务(一):SpringTask使用
背景:在日常开发中,经常会用到任务调度这类程序.实现方法常用的有:A. 通过java.util.Timer.TimerTask实现. B.通过Spring自带的SpringTask. C. 通过Spr ...
- Jmeter4.0版本实现背景色切换
今天下载了Jmeter4.0新版本,看着这高大上的黑曜石般的界面,着实不适应. 尤其是在右击,希望enable和disable一个线程组时候,老眼昏花,不太看得清楚哪一个是灰色的不能点击 花了时间看了 ...
- unity零基础开始学习做游戏(四)biu~biu~biu发射子弹打飞机
-------小基原创,转载请给我一个面子 主角都能移动了,那不得做点什么伸张正义,守护世界和平的事嘛,拿起家伙biu~biu~biu~ 首先得做一个好人和一个坏人 老规矩,Canvas下创建两个Im ...
- Linux/Windows 文件交互读取转义字符变换
- php添加日志文件
记录一下. 有时候写测试代码的时候,不习惯直接在屏幕上输出反馈,那么可以配置日志文件,把需要输出的内容追加到日志文件里面,就很方便. Php自带日志系统,可以参考网上的博客配置. 我要说的是,如果你的 ...
- Mysql分页查询性能分析
[PS:原文手打,转载说明出处,博客园] 前言 看过一堆的百度,最终还是自己做了一次实验,本文基于Mysql5.7.17版本,Mysql引擎为InnoDB,编码为utf8,排序规则为utf8_gene ...
- 初探Apache Beam
文章作者:luxianghao 文章来源:http://www.cnblogs.com/luxianghao/p/9010748.html 转载请注明,谢谢合作. 免责声明:文章内容仅代表个人观点, ...
- OCR智能识别身份信息
本人研究了两款OCR智能识别的API,下面做详解! 第一款是百度云的OCR识别,填写配置信息,每天有五百次免费的识别次数,适合中小型客户流量可以使用.API文档:http://ai.baidu.com ...