小象涂色
难度级别:C; 运行时间限制:1000ms; 运行空间限制:262144KB; 代码长度限制:2000000B
试题描述

小象喜欢为箱子涂色。小象现在有c种颜色,编号为0~c-1;还有n个箱子,编号为1~n,最开始每个箱子的颜色为1。小象涂色时喜欢遵循灵感:它将箱子按编号排成一排,每次涂色时,它随机选择[L,R]这个区间里的一些箱子(不选看做选0个),为之涂上随机一种颜色。若一个颜色为a的箱子被涂上b色,那么这个箱子的颜色会变成(a*b)modc。请问在k次涂色后,所有箱子颜色的编号和期望为多少?

输入
第一行为T,表示有T组测试数据。
对于每组数据,第一行为三个整数n,c,k。
接下来k行,每行两个整数Li,Ri,表示第i个操作的L和R。
输出
对于每组测试数据,输出所有箱子颜色编号和的期望值,结果保留9位小数。
输入示例
3
3 2 2
2 2
1 3
1 3 1
1 1
5 2 2
3 4
2 4
输出示例
2.062500000
1.000000000
3.875000000
其他说明
数据范围:
40%的数据1 <= T <= 5,1 <= n, k <= 15,2 <= c <= 20
100%的数据满足1 <= T <= 10,1 <= n, k <= 50,2 <= c <= 100,1 <= Li <= Ri <= n

首先,操作顺序是没有影响的,那么我们可以记录每个位置进行了多少次操作。

就可以写个DP,得出每个位置进行若干次操作后的期望颜色。

#include<cstdio>
#include<cctype>
#include<queue>
#include<cmath>
#include<cstring>
#include<algorithm>
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define dwn(i,s,t) for(int i=s;i>=t;i--)
#define ren for(int i=first[x];i;i=next[i])
using namespace std;
inline int read() {
    int x=0,f=1;char c=getchar();
    for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
    for(;isdigit(c);c=getchar()) x=x*10+c-'0';
    return x*f;
}
double f[55][105];
int n,c,k,cnt[55];
int main() {
    dwn(T,read(),1) {
        n=read();c=read();k=read();    
        memset(f,0,sizeof(f));
        memset(cnt,0,sizeof(cnt));
        f[0][1]=1;
        rep(t,0,k-1) rep(j,0,c-1) {
            f[t+1][j]+=f[t][j]*0.5;
            rep(k,0,c-1) f[t+1][(j*k)%c]+=f[t][j]*(0.5/c);             
        }
        double ans=0;  
        rep(i,1,k) {
           int l=read(),r=read();
           rep(j,l,r) cnt[j]++;           
        }
        rep(i,1,n) rep(j,0,c-1) ans+=f[cnt[i]][j]*j;
        printf("%.9lf\n",ans);
    }
    return 0;    
}
View Code

相关文章: