概率dp+状压dp C. LRU 暑训第五天

C. LRU 概率dp+状压dp

题目大意:

有一个缓存,它最多可以存k条记录,如果超过k条记录,那么最早存进去的记录会被删除,如果其中有一条记录之前已经存过,那么会更新这条记录的时间,并且将之前的那条记录删除。

第一行,给你n条记录和缓存的大小k,第二行,给你每条记录存进缓存的概率,问经过无穷次存储之后,最后每条记录存进缓存的概率。

题解:

这种概率题目我其实很不擅长,又涉及到无穷,更是一头雾水。。。

从后往前考虑!!!考虑最后是一个什么样的状态

考虑中间状态形成的原因以及概率的求法:

  • 第一种:自增,假设原来缓存已经有1、2,那么又变成1、2这种状态是可以1这条记录或者2这条记录加进缓存,这个就是自增
  • 第二种:其他状态转移过来,假设状态是1、2,那么是不是可以从两种状态转移过来,第一种就是缓存1这条记录,第二种就是缓存有2这条记录

考虑最后状态形成的原因以及概率的求法:

  • 这个最后一个状态和中间状态肯定是不一样的,因为最后一个状态确定之后,这个缓存就不会改变了,因为都已经是最后的状态了,这个时候就只需要求最后状态的概率。

  • 最后的这个状态是肯定不会是自增形成的,因为如果是自增,那么永远填不满这k个值,因为重复的元素要被删除。所以最后一个状态只能从其他状态转移过来。

知道这些之后就可以列式子了,

(dp[i]=sum(p[j])*dp[i]+sum(dp[i igotimes (1<<j)]*p[j]))

因为 (dp[i]) 表示 (i) 这种状态的出现的概率之和,所以 (dp[0]=1) 因为一开始的(dp[0]=1) 之后永远都不会出现缓存是0条记录的情况,所以可知 (dp[0]=1)

#include <bits/stdc++.h>
#define id first
#define val second
#define inf 0x3f3f3f3f
#define inf64 0x3f3f3f3f3f3f3f3f
using namespace std;
const int maxn=25;
const double eps = 1e-8;
typedef long long ll;
double dp[1<<21],p[maxn],ans[maxn];

int main(){
    int n,k,now=0;
    scanf("%d%d",&n,&k);
    for(int i=0;i<n;i++) {
    	scanf("%lf",&p[i]);
    	if(p[i]>eps) now++;
    }
    dp[0]=1;
    k=min(k,now);
    for(int i=1;i<(1<<n);i++){
        int x= i,num=0;
        double sum=0,res=1.0;
        for(int j=0;j<n;j++){
            int tmp=x&(1<<j);
            if(tmp) {
                num++;
                res-=p[j];
                sum+=p[j]*dp[x^(1<<j)];
            }
        }
        if(num==k) {
//        	printf("kk   dp[%d]=%f sum=%f res=%f
",i,dp[i],sum,res);
            dp[i]=sum;
            for(int j=0;j<n;j++){
                int tmp=x&(1<<j);
                if(tmp) ans[j]+=dp[i];
            }
        }
        if(num<k) dp[i]=sum/res;
//        if(!((i&(1<<3))||(i&(1<<5))||(i&(1<<7))||(i&(1<<9))
//		||(i&(1<<11))||(i&(1<<13))||(i&(1<<15))||(i&(1<<16))||(i&(1<<17))||(i&(1<<18))||(i&(1<<19)))){
//        	printf("dp[%d]=%f sum=%f res=%f
",i,dp[i],sum,res);
//
//		}
    }
    for(int i=0;i<n;i++) printf("%.10f ",ans[i]);
    printf("
");
}

原文地址:https://www.cnblogs.com/EchoZQN/p/13261238.html