【题目】C. LRU

【题意】给定空间为k的背包和n个物品,每次每个物品有pi的概率加入(Σpi=1),加入时若发现背包中已有该物品则不改变,若背包满k个物品后再加入新物品则弹出最早加入的物品,求加入10^100次后每个物品在背包中的概率。n,k<=20

【算法】概率DP

【题解】进行10^100次加入后背包一定是满的且是最后加入的k个物品,所以问题转化为在空背包中加入物品至满,各个物品在背包中的概率。

设$f_S$表示背包中的物品状态为S的概率,最后只需要统计所有恰好k个1的状态对物品的贡献即可。

根据全概率公式,P(A)=ΣP(Bi)*P(A|Bi),有:

f[S]=Σf[S-2^(j-1)]*p[j]+f[S]*Σp[j],S&2^(j-1)=1

移项得f[S]=Σf[S-2^(j-1)]*p[j]/sum(S),其中sum(S)是状态S中为0的物品的概率之和。

注意,当状态S为答案状态(k)时,统计不应该除以sum(S),因为已满之后就不填了。

★特别注意,当物品中不满k件概率不为0时,背包容量应降为概率不为0的物品件数。

#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=,maxN=;
int n,k;
double p[maxn],f[maxN],ans[maxn];
int main(){
scanf("%d%d",&n,&k);
int cnt=n;
for(int i=;i<=n;i++)scanf("%lf",&p[i]),cnt-=p[i]<1e-?:;
k=min(cnt,k);//
f[]=;
for(int S=;S<(<<n);S++){
f[S]=;
int num=;double sum=;
for(int i=;i<n;i++)if(S&(<<i))num++;else sum+=p[i+];
if(num>k)continue;
for(int i=;i<n;i++)if(S&(<<i)){
f[S]+=f[S-(<<i)]*p[i+];
}
if(num==k){
for(int i=;i<n;i++)if(S&(<<i))ans[i+]+=f[S];
}
f[S]/=sum;//
}
for(int i=;i<=n;i++)printf("%.10lf ",ans[i]);
return ;
}

最新文章

  1. 初步学习border-radius
  2. 【读书笔记《Bootstrap 实战》】1.初识Bootstrap
  3. Android Animation学习(二) ApiDemos解析:基本Animators使用
  4. go学习与记录
  5. html5,表单
  6. UVa 二分图匹配 Examples
  7. ###学习《C++ Primer》- 2
  8. 10.31 afternoon
  9. python ——面向对象进阶
  10. LINUX:alias命令详解
  11. Angular 4 自定义组件封装遇见的一些事儿
  12. Java基础&amp;面向对象(二)
  13. MATLAB raw格式转为bmp格式
  14. lfs(systemd版本)学习笔记-第1页
  15. Music in Car CodeForces - 746F (贪心,模拟)
  16. 像素 转换 px dp
  17. linux 如何开通新的端口
  18. 【BLE】CC2541之发现服务与特征值
  19. 负载均衡层次结构:LVS Nginx DNS CDN
  20. 【Android开发】之MediaPlayer的错误分析

热门文章

  1. 第5题 查找字符串中的最长回文字符串---Manacher算法
  2. shader language学习(1)——shader language简介背景
  3. JavaScript判断密码强度
  4. Java对象空间分配流程
  5. 第197天:js---caller、callee、constructor和prototype用法
  6. 【Python】Python基础教程系列目录
  7. EM算法【转】
  8. [十六]SpringBoot 之 读取环境变量和绑定属性对象
  9. Going in Cycle!! UVA - 11090(二分+判断环路 )
  10. [洛谷P4563][JXOI2018]守卫