Codeforces698C. LRU

Posted Blue233333

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces698C. LRU相关的知识,希望对你有一定的参考价值。

n<=20种东西,有个大小k<=n的箱子,每次会以固定的概率从所有东西里选一种,若箱子里有空位且这种东西没出现过就丢进去,若箱子满了且这种东西没出现过就把最早访问过的一个丢掉,(只要在每次操作最早的“挑一种物品”选中某个数都算“访问”)问10^100操作后每个数存在箱子里的概率。

由于操作过多,最后箱子可以看成满的。可以发现由于操作跟时间有关,只有最后新进入箱子的k种东西在进入箱子时会对答案产生影响,因此只用看后面几次操作即可。可以把这个过程等同于:从头开始拿,问刚把箱子填满时的概率。

在后面的操作中,虽然只看最后k种东西被访问的过程,但期间也有可能多次访问到同种东西,咋办呢?状压,f(i)表示状态i出现的概率,$f(i)=\sum f(j)*a_{j关于i的补集}+\sum_{k\epsilon i} a_k*f(i)$,错误!最终状态不会再自己转移到自己,所以判一下i是不是终态即有没有k个数,没有才把后面那部分算上去。

还错!数据中有一些是箱子不可能满,所以要把箱子大小和概率>0的种数取个min。

技术分享图片
 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdlib>
 4 #include<cstdio>
 5 //#include<bitset>
 6 #include<algorithm>
 7 #include<cmath>
 8 using namespace std;
 9 
10 int n,K;
11 #define maxn 1100011
12 double a[33],ans[maxn],eve[33];
13 int main()
14 {
15     scanf("%d%d",&n,&K);
16     int cnt=n;
17     for (int i=1;i<=n;i++) scanf("%lf",&a[i]),cnt-=a[i]<1e-10?1:0;
18     K=min(cnt,K);
19     ans[0]=1; for (int i=1;i<=n;i++) eve[i]=0;
20     for (int i=1;i<(1<<n);i++)
21     {
22         int one=0; ans[i]=0; double kk=0;
23         for (int j=1;j<=n;j++) if ((i>>(j-1))&1) one++,ans[i]+=ans[i^(1<<(j-1))]*a[j],kk+=a[j];
24         if (one==K) for (int j=1;j<=n;j++) if ((i>>(j-1))&1) eve[j]+=ans[i];
25         ans[i]/=(1-kk);
26     }
27     for (int i=1;i<=n;i++) printf("%.8lf ",eve[i]);
28     return 0;
29 }
View Code

 

以上是关于Codeforces698C. LRU的主要内容,如果未能解决你的问题,请参考以下文章

CodeForces698 C. LRU

codeforces 698CLRU

codeforces 698F

CodeForces 698A Vacations

CodeForces 698A Vacations

Codeforces 698A - Vacations - [简单DP]