Codeforces 698C LRU 概率+状压

来源:互联网 发布:windows怎么开发苹果 编辑:程序博客网 时间:2024/05/29 13:12
题意:有一个箱子最多装k件物品,现在有n件物品,第i件物品被询问的概率为pi,当第i件物品被询问时,如果第i件物品不在箱子里面,则把第i件物品加入到箱子中,若箱子物品数量>k,则移除最早添加进来的物品.
问10^100次查询后,每个物品在箱子中的概率? n,k<=20.

询问10^100次,物品最多只有20个,所以可以说箱子最后肯定有k个物品
问题转化为求最后状态为S的概率,初始时抽到k种不同物品的状态S'和S一一映射.

转移状态时合并GS的和得:dp[i|(1<<j)]=dp[i]*p[j]/(1-sum) 

#include <bits/stdc++.h>using namespace std;typedef long long ll;const ll inf=0x3f3f3f3f;const int N=1<<21;double dp[N],p[21],ans[21];int n,k;int main(){while(cin>>n>>k){int cnt=0;for(int i=0;i<n;i++){cin>>p[i];if(p[i]>0)cnt++;}memset(dp,0,sizeof(dp));k=min(k,cnt);dp[0]=1.0;for(int i=0;i<(1<<n);i++){cnt=0;double sum=0;for(int j=0;j<n;j++){if((i>>j)&1)cnt++,sum+=p[j];}for(int j=0;j<n;j++){if(!((i>>j)&1))dp[i|(1<<j)]+=dp[i]*p[j]/(1.0-sum);}if(cnt==k){for(int j=0;j<n;j++){if((i>>j)&1)ans[j]+=dp[i];}}}for(int i=0;i<n;i++)printf("%.10lf ",ans[i]);printf("\n");}return 0; } 


原创粉丝点击