题意:给定n个数a1…an(n<=50,ai<=50),随机打乱后,记Si=a1+a2+a3…+ai,问满足Si<=p的i的最大值的期望.(p<=50)

这道题在网上有一些不同的做法,O(n^3)或O(n^4)都可以通过,这里整合一下,标上出处,其实我只写了自己YY的那一种,叫我搬运工

  1.期望的线性性,讨论每个数对i的贡献.O(n^4)

  自己YY的,不知道以前有没有人也写过这种方法.

  如果ai满足Si<=p,那么ai就对答案有1 的贡献,因此我们算出每个数ai满足Si<=p的概率(其实也是对答案贡献的期望),加起来就是答案.

  现在对于每个数考虑满足条件的概率,我们不妨考虑将这个数先放进序列里,再随机往序列里加数.如果现在这个数的前面有i个数,后面有j个数,那么再随机加一个数位于这个数前面的概率是(i+1)/(i+1+j+1),(j+1)/(i+1+j+1),因为这个数的前面有i+1个空,后面有j+1个空,而且新加的数插到每个空的概率是相同的.

  那么我们定义F[i][j][s]表示这个数前面有i个数,后面有j个数,前面的数的和为s的情况在构造整个序列的中间过程中出现的概率,则F[i][j][s]=F[i][j-1][s]*p(最后一个数插在后面)+F[i-1][j][s-a[last]]*p(最后一个数插在前面),其中p(最后一个数插在后面)=(j)/(i+j+1),

  p(最后一个数插在前面)=(i+1)/(i+j+1).边界F[0][0][0]=1,也就是一开始我们的序列里只有一个数.

  于是我们做n次O(n^3)的DP即可.

  看上去我们每次DP生成这个随机序列的方式不同,但这些方式其实是等价的,因为每个数都是随机插入.

  写的时候可以通过恰当的循环顺序把DP数组只开两维,不过并没有卡内存.

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
double f[][];//f[i][j]:前面有j个人,长度之和为i
int a[];
int lim,n;
double dp(int x){
memset(f,,sizeof(f));
f[][]=;
int flag=;
for(int i=;i<=n;++i){
if(i==x){
flag=;continue;
}
for(int j=;j>=;--j){
for(int k=;k>=;--k){
f[min(j+a[i],)][k+]+=f[j][k]*(k+)/(i-flag+);
f[j][k]=f[j][k]*(i-flag-k)/(i-flag+);
}
}//printf("%.3f\n",f[0][0]);
}
double ans=;
for(int i=;i+a[x]<=lim;++i)
for(int j=;j<=n;++j)//printf("%d %d %d %.3f\n",x,i,j,f[i][j])
ans+=f[i][j];
// printf("%.3f\n",ans);
return ans;
}
int main(){
scanf("%d",&n);
for(int i=;i<=n;++i){
scanf("%d",a+i);
}
scanf("%d",&lim);
double ans=;
for(int i=;i<=n;++i)ans+=dp(i);
printf("%.5f\n",ans);
return ;
}

  2.期望的定义,O(n^4)

  传送门:http://blog.csdn.net/hmzhe/article/details/51960298

  我们知道所有可能的排列一共有n!种,50!虽然是一个很大的数字,但double可以提供足够的精度(有一定的精度损失,但最终结果损失的精度在题目要求的1e-4之外).因此我们可以算出所有排列中的答案之和再除以n!就是答案.

  显然我们不能用阶乘的时间复杂度真正地枚举所有答案.因此我们需要将某些具有相同特征的排列一并计算.注意到,如果一个方案在Si<=p时只算进去前m个数,那么后(n-m)个数如何排列我们是不关心的.也就是说我们可以得到一共(n-m)!个方案.

  那么我们只需要考虑算了0个数的方案有几个,算了1个数的方案有几个,算了2个数的方案有几个….这里的方案数也可能很大,需要double(最终结果会炸掉不影响答案正确性的1e-4之后精度,中间炸的精度可能大一点但除以n!后就变到1e-4之后了).

  此时我们需要确保我们所计数的”算了一个数的方案”不会在加一个数之后变成”算了两个数的方案”,所以我们需要确保这个方案所选择的前缀在末尾加了一个数之后和大于p,也就是我们需要定义F[i][j][s][ed]为在前i个数中选取j个和为s的数,且在这些数的最后加上一个数ed后超过限制的方案数.这个ed似乎不太好处理,所以我们应当在最外层枚举它.最后只有s<p且s+a[ed]>p的状态合法.x后面的数字自由排列,所以方案数乘上(n-j-1)!如果在计算选取方案的时候没有考虑顺序,最后需要对前面j个数也进行排列,方案数乘上j!

  3.期望的线性性,O(n^3)

  传送门:http://blog.sina.com.cn/s/blog_140e100580102wj4e.html

  做法1.中我们考虑了原序列中每个数对期望的贡献.实际上我们可以转而考虑最终序列中每个位置上的数对期望的贡献,那么不需要考虑每种方案的截止位置,只需要考虑无序选出i个数和为j(j<p)的方案数x即可得出第i个位置对最终答案的贡献x*(i!)*(n-i)!/n!

  4.期望的线性性,O(n^3)

  codeforces别人的一份AC代码:http://codeforces.com/contest/261/submission/2917070

  可以发现我们在做法3中算的其实是每个位置对答案贡献的期望.直接定义F[i][j][k]为在原序列的前i个数中选取了最终序列的前j个数,且和为k的情况在所有情况中所占的概率.写法和3相似.

CodeForces 261B Maxim and Restaurant 解法汇总的更多相关文章

  1. codeforces 261B Maxim and Restaurant(概率DP)

    B. Maxim and Restaurant time limit per test 2 seconds memory limit per test 256 megabytes input stan ...

  2. CodeForces - 261B Maxim and Restaurant

    http://codeforces.com/problemset/problem/261/B 题目大意:给定n个数a1-an(n<=50,ai<=50),随机打乱后,记Si=a1+a2+a ...

  3. cf 261B.Maxim and Restaurant

    什么什么期望的,不会! (题解http://blog.sina.com.cn/s/blog_140e100580102wj4e.html(看不懂)) #include<bits/stdc++.h ...

  4. 【CodeForces 261B】Maxim and Restaurant(DP,期望)

    题目链接 第一种解法是$O(n^3*p)$的:f[i][j][k]表示前i个人进j个人长度为k有几种方案(排列固定为123..n时).$f[i][j][k]=f[i-1][j][k]+f[i-1][j ...

  5. Codeforces Round #160 (Div. 2) D. Maxim and Restaurant(DP)

    题目链接 想了挺久,枚举每一件物品,当做关键物品,假设再加这一件物品,就>=c了,把剩下的物品背一下包,dp[i][j]表示i个物品可以组成重量j的个数. 这样就可以知道前面放i件,后边肯定放n ...

  6. 整数划分问题-解法汇总(暂有DP-递归)

    整数划分问题是一个锻炼组合数学,递归以及动态规划很好的例子,虽然问题看似简单,但是其中玄机万千,有人转化成为背包问题,有人用生成函数解,有人以此作为企业面试题目,可见这种问题的认可度还是很高的. 整数 ...

  7. Codeforces Round #423 A Restaurant Tables(模拟)

    A. Restaurant Tables time limit per test 1 second memory limit per test 256 megabytes input standard ...

  8. Codeforces 854B Maxim Buys an Apartment:贪心

    题目链接:http://codeforces.com/contest/854/problem/B 题意: 有n栋房子从1到n排成一排,有k栋房子已经被售出. 现在你要买一栋“好房子”. 一栋房子是“好 ...

  9. Codeforces F. Maxim and Array(构造贪心)

    题目描述: Maxim and Array time limit per test 2 seconds memory limit per test 256 megabytes input standa ...

随机推荐

  1. 使用Ring Buffer构建高性能的文件写入程序

    最近常收到SOD框架的朋友报告的SOD的SQL日志功能报错:文件句柄丢失.经过分析得知,这些朋友使用SOD框架开发了访问量比较大的系统,由于忘记关闭SQL日志功能所以出现了很高频率的日志写入操作,从而 ...

  2. 《.NET开发资源大全》

    目录 API 应用框架(Application Frameworks) 应用模板(Application Templates) 人工智能(Artificial Intelligence) 程序集处理( ...

  3. python语言中的编码问题

    在编程的过程当中,常常会遇到莫名其妙的乱码问题.很多人选择出了问题直接在网上找答案,把别人的例子照搬过来,这是快速解决问题的一个好办法.然而,作为一个严谨求实的开发者,如果不从源头上彻底理解乱码产生的 ...

  4. 读取数据库数据,并将数据整合成3D饼图在jsp中显示

    首先我将生成饼图的方法独立写成一个PieChar.java类,详细代码如下:(数据库需要自己建,如有需要的话) import java.io.IOException; import java.sql. ...

  5. ABAP关键字SUBMIT的简单例子和学习小记

    网上有关SUBMIT实现程序调用的例子稍显复杂,而相关的参考和解释则不是很完善.本文给出一个SUBMIT的小示例程序(代码见文末),实现了最简单的程序间调用及返回值,以及SAP官方文档中相关内容的翻译 ...

  6. react-native DatePicker日期选择组件的实现

    本教程的实现效果如下: 为了实现其淡入/淡出的覆盖效果, 还有取消按钮, 在此用了一个三方的组件, 大家可以先安装一下: 三方组件的地址:https://github.com/eyaleizenber ...

  7. 看看C# 6.0中那些语法糖都干了些什么(中篇)

    接着上篇继续扯,其实语法糖也不是什么坏事,第一个就是吃不吃随你,第二个就是最好要知道这些糖在底层都做了些什么,不过有一点 叫眼见为实,这样才能安心的使用,一口气上五楼,不费劲. 一:字符串嵌入值 我想 ...

  8. 3、项目资源的提供 - PMO项目管理办公室

    PMO项目管理办公室也需要对项目相关的资源进行提供,从而针对项目的资源也进行标准化和规范化的管理.也就是说,PMO项目管理办公室就是提供项目相关的规范化资源内容,从而统一管理项目相关的内容,达到规范的 ...

  9. Oracle学习笔记十四 内置程序包

    扩展数据库的功能 为 PL/SQL 提供对 SQL 功能的访问 用户 SYS 拥有所有程序包 是公有同义词 可以由任何用户访问 一些内置程序包 程序包名称 说明 STANDARD和DBMS_STAND ...

  10. 腾讯php经历

    12年毕业至今,一年C#,2年php,几个月node,因为一些原因再次离职,接到腾讯互娱的php面试电话,匆匆准备了一番,便去了科兴科技园腾讯的高大上办公楼. 1.笔试 试题大部分网上都有,例如: 用 ...