B elephant

小象涂色 (elephant.pas/.c/.cpp)

时间限制:1s,空间限制 128MB

题目描述: 小象喜欢为箱子涂色。小象现在有 c 种颜色,编号为 0~c-1;还有 n 个箱子,编号为 1~n,最开始每个箱子的颜色为 1。小象涂色时喜欢遵循灵感:它将箱子按编号排成一排, 每次涂色时,它随机选择[L,R]这个区间里的一些箱子(不选看做选 0 个),为之涂上随机 一种颜色。若一个颜色为 a 的箱子被涂上 b 色,那么这个箱子的颜色会变成(a*b)mod c。请问在 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,预处理最大操作次数,设置 f[i][j] 表示第 i 次操作染成第 j 个颜色的概率。可以判断对于每一次操作有1/2的概率不染色,有(1/2)*(1/c)的概率染成第k种颜色,所以 f[i][j] 转移方程为:
 f[i+1][j]+= f[i][j] *(1/2);

 f[i+1][(j*b)/c]+= f[i][j] *[(1/2)*(1/c)];

 最后结果 ∑f[i][j]*j

代码:

#include<bits/stdc++.h>
using namespace std;

int t,n,c,k;
int a[10200];
double f[55][3000];
int maxn;
double ans;

void work()
{
        f[0][1]=1;
        for(int i=0;i<maxn;i++){
            for(int j=0;j<c;j++)
            {
                f[i+1][j]+=f[i][j]/2;
                for(int k=0;k<c;k++)
                {
                    f[i+1][(j*k)%c]+=f[i][j]/(2*c);
                }
            }
        }
        ans=0;
        for(int i=1;i<=n;i++)
            for(int j=0;j<c;j++){
                ans+=f[a[i]][j]*j;
            }
            
        printf("%.9lf
",ans);
}

int main()
{
    cin>>t;
    while(t--)
    {
        maxn=0;
        memset(a,0,sizeof(a));
        memset(f,0,sizeof(f));
        cin>>n>>c>>k;
        for(int i=1;i<=k;i++){
            int x,y;
            cin>>x>>y;
            for(int j=x;j<=y;j++)
            {
                a[j]++;maxn=max(maxn,a[j]);
            }
        }
//        cout<<maxn<<"pcakvp
";
        work();
    }
    
}
原文地址:https://www.cnblogs.com/yxr001002/p/14226163.html