题目描述
小象喜欢为箱子涂色。小象现在有
c
种颜色,编号为0~
输入描述
第一行为
对于每组数据,第一行为三个整数
接下来
k
行,每行两个整数
输出描述
对于每组测试数据,输出所有箱子颜色编号和的期望值,结果保留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%的数据
100%的数据满足
1<=T<=10
,
1<=n,k<=50
,
2<=c<=100
,
1<=Li<=Ri<=n
。
思路
黄学长博客:
若用 f[i][j] 表示第 i 个箱子染成颜色
j ,似乎复杂度比较奇怪
发现每个箱子是一样的,那么只要得出任意箱子染 i 次最终颜色j ,就可以解决啦。。。
补充:
fi,j
表示任意一个箱子染
i
次得到颜色
代码
#include <cstdio>
#include <cstring>
const int maxn=50;
const int maxc=100;
int n,c,ki,sum[maxn+10],t;
double f[maxn+10][maxc+10],ans;
int solve()
{
memset(f,0,sizeof f);
memset(sum,0,sizeof sum);
ans=0;
f[0][1]=1;
scanf("%d%d%d",&n,&c,&ki);
for(int i=1; i<=ki; i++)
{
int a,b;
scanf("%d%d",&a,&b);
sum[a]++;
sum[b+1]--;
}
for(int i=1; i<=n; i++)
{
sum[i]+=sum[i-1];
}
for(int i=0; i<ki; 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);
}
}
}
for(int i=1; i<=n; i++)
{
for(int j=0; j<c; j++)
{
ans+=j*f[sum[i]][j];
}
}
printf("%.9lf\n",ans);
return 0;
}
int main()
{
scanf("%d",&t);
while(t--)
{
solve();
}
return 0;
}