codeforces 698 C. LRU (概率与期望+状压DP)
2017-03-15 18:45
441 查看
C. LRU
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
While creating high loaded systems one should pay a special attention to caching. This problem will be about one of the most popular caching algorithms called LRU (Least Recently Used).
Suppose the cache may store no more than k objects. At the beginning of the workflow the cache is empty. When some object is queried
we check if it is present in the cache and move it here if it's not. If there are more than k objects in the cache after this, the
least recently used one should be removed. In other words, we remove the object that has the smallest time of the last query.
Consider there are n videos being stored on the server, all of the same size. Cache can store no more than k videos
and caching algorithm described above is applied. We know that any time a user enters the server he pick the video i with probability pi.
The choice of the video is independent to any events before.
The goal of this problem is to count for each of the videos the probability it will be present in the cache after 10100 queries.
Input
The first line of the input contains two integers n and k (1 ≤ k ≤ n ≤ 20) —
the number of videos and the size of the cache respectively. Next line contains n real numbers pi (0 ≤ pi ≤ 1),
each of them is given with no more than two digits after decimal point.
It's guaranteed that the sum of all pi is
equal to 1.
Output
Print n real numbers, the i-th
of them should be equal to the probability that the i-th video will be present in the cache after 10100queries.
You answer will be considered correct if its absolute or relative error does not exceed 10 - 6.
Namely: let's assume that your answer is a, and the answer of the jury is b.
The checker program will consider your answer correct, if
![](http://codeforces.com/predownloaded/c6/2e/c62ea64d4651240724c5ac4779b671c741edec24.png)
.
Examples
input
output
input
output
input
output
input
output
题目大意:有一个大小为k的缓存区,每次从n种物品中按照一定的概率选取一种物品尝试放进去.同一个物品每一次选取的概率都是相同的.如果这种物品已经放进去过就不再放进去.如果缓存区满了就把放进去的时间离现在最远的物品拿出来.问10^100次后每个物品在缓冲区中的概率.
题解:概率与期望+状压DP
如果是正着考虑,那么我们会出现很多废弃的状态。而且还会出现进去的被弹出来的情况,十分不好想。那么我们倒着考虑,那么最后一次加入的一定在最终的集合中。因为10^100基本上接近无限了,那么最后的集合一定是满的。
也就是一定存在k个不同的物品。
dp[i]表示到达状态i的概率。
dp[i|(1<<j)]+=dp[i]*p[j] j不在i中。注意的是没次选择还有一定的概率选择到i集合中的数。所以dp[i]/=(1-sum) sum表示i集合中数的概率。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define N 21
using namespace std;
int n,k;
double ans[1<<N],f[1<<N],p
;
int main()
{
freopen("a.in","r",stdin);
scanf("%d%d",&n,&k); int c=0;
for (int i=0;i<n;i++) {
scanf("%lf",&p[i]);
if (p[i]!=0) c++;
}
k=min(k,c);
f[0]=1;
for (int i=0;i<(1<<n);i++) {
double cnt=0,now=0;
for (int j=0;j<n;j++)
if ((i>>j)&1) cnt++,now+=p[j];
if (cnt==k) {
for (int j=0;j<n;j++)
if ((i>>j)&1) ans[j]+=f[i];
continue;
}
if (cnt>k) continue;
if (1.0-now==0) continue;
f[i]/=(1.0-now);
for (int j=0;j<n;j++)
if (!((i>>j)&1)) f[i|(1<<j)]+=f[i]*p[j];
}
for (int i=0;i<n;i++) printf("%.12lf%c",ans[i]," \n"[i==n-1]);
}
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
While creating high loaded systems one should pay a special attention to caching. This problem will be about one of the most popular caching algorithms called LRU (Least Recently Used).
Suppose the cache may store no more than k objects. At the beginning of the workflow the cache is empty. When some object is queried
we check if it is present in the cache and move it here if it's not. If there are more than k objects in the cache after this, the
least recently used one should be removed. In other words, we remove the object that has the smallest time of the last query.
Consider there are n videos being stored on the server, all of the same size. Cache can store no more than k videos
and caching algorithm described above is applied. We know that any time a user enters the server he pick the video i with probability pi.
The choice of the video is independent to any events before.
The goal of this problem is to count for each of the videos the probability it will be present in the cache after 10100 queries.
Input
The first line of the input contains two integers n and k (1 ≤ k ≤ n ≤ 20) —
the number of videos and the size of the cache respectively. Next line contains n real numbers pi (0 ≤ pi ≤ 1),
each of them is given with no more than two digits after decimal point.
It's guaranteed that the sum of all pi is
equal to 1.
Output
Print n real numbers, the i-th
of them should be equal to the probability that the i-th video will be present in the cache after 10100queries.
You answer will be considered correct if its absolute or relative error does not exceed 10 - 6.
Namely: let's assume that your answer is a, and the answer of the jury is b.
The checker program will consider your answer correct, if
![](http://codeforces.com/predownloaded/c6/2e/c62ea64d4651240724c5ac4779b671c741edec24.png)
.
Examples
input
3 1 0.3 0.2 0.5
output
0.3 0.2 0.5
input
2 1 0.0 1.0
output
0.0 1.0
input
3 2 0.3 0.2 0.5
output
0.675 0.4857142857142857 0.8392857142857143
input
3 3 0.2 0.3 0.5
output
1.0 1.0 1.0
题目大意:有一个大小为k的缓存区,每次从n种物品中按照一定的概率选取一种物品尝试放进去.同一个物品每一次选取的概率都是相同的.如果这种物品已经放进去过就不再放进去.如果缓存区满了就把放进去的时间离现在最远的物品拿出来.问10^100次后每个物品在缓冲区中的概率.
题解:概率与期望+状压DP
如果是正着考虑,那么我们会出现很多废弃的状态。而且还会出现进去的被弹出来的情况,十分不好想。那么我们倒着考虑,那么最后一次加入的一定在最终的集合中。因为10^100基本上接近无限了,那么最后的集合一定是满的。
也就是一定存在k个不同的物品。
dp[i]表示到达状态i的概率。
dp[i|(1<<j)]+=dp[i]*p[j] j不在i中。注意的是没次选择还有一定的概率选择到i集合中的数。所以dp[i]/=(1-sum) sum表示i集合中数的概率。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define N 21
using namespace std;
int n,k;
double ans[1<<N],f[1<<N],p
;
int main()
{
freopen("a.in","r",stdin);
scanf("%d%d",&n,&k); int c=0;
for (int i=0;i<n;i++) {
scanf("%lf",&p[i]);
if (p[i]!=0) c++;
}
k=min(k,c);
f[0]=1;
for (int i=0;i<(1<<n);i++) {
double cnt=0,now=0;
for (int j=0;j<n;j++)
if ((i>>j)&1) cnt++,now+=p[j];
if (cnt==k) {
for (int j=0;j<n;j++)
if ((i>>j)&1) ans[j]+=f[i];
continue;
}
if (cnt>k) continue;
if (1.0-now==0) continue;
f[i]/=(1.0-now);
for (int j=0;j<n;j++)
if (!((i>>j)&1)) f[i|(1<<j)]+=f[i]*p[j];
}
for (int i=0;i<n;i++) printf("%.12lf%c",ans[i]," \n"[i==n-1]);
}
相关文章推荐
- Codeforces 696B. Puzzles (概率DP求期望)
- [HDU4336]Card Collector(概率期望+状压dp)
- codeforces 16E 概率+状压dp
- hdu 4336 Card Collector (概率与期望+状压DP)
- CodeForces 167B - Wizards and Huge Prize 期望概率dp
- codeforces 16E Fish (概率-期望DP)
- codeforces 183d(期望概率dp)
- Codeforces 839C Journey (树形dp + 概率期望)
- Codeforces 280C Game on Tree 概率dp 树上随机删子树 求删完次数的期望
- 【Codeforces Round 363 (Div 2) E】【概率DP 期望DP 逆推等价法】LRU Cache替换LRU原则超多步数后每个数据在Cache中的概率
- CodeForces 698 C. LRU(状压DP)
- BZOJ 3270 博物馆 && CodeForces 113D. Museum 期望概率dp 高斯消元
- Codeforces 513C Second price auction 概率dp 求期望
- hdu4405(概率DP求期望)
- Codeforces 678E Another Sith Tournament(状压dp,概率dp)
- hdu 4405 Aeroplane chess(简单概率dp 求期望)
- Codeforces-148D Bag of mice (概率DP)
- HDU 3853 LOOPS(概率DP求期望)
- HDU 3853 LOOP (概率DP求期望)
- Codeforces 24D 期望DP 解题报告