高次osu
题目链接
~~ (描述太长了就不截了)~~
这是一道osu的延展题,不过它每次对期望的贡献值为x的k次方,k的范围为1到10。对于每次贡献的增量为x+1的k次方减x的k次方,然后可以使用二项展开式用于计算,但是和经典的osu问题一样需要维护x的1次方到x的k-1次方,存储在x数组里,然后把x+=的结果存在y数组里,因为osu里最后的贡献不含上次x的k次方需要先存起来,最后减去此项的结果维护最后的结果就行了。
#include <bits/stdc++.h>
using namespace std;
int n,k;
double x[11],p,y[11];
double C(int m,int i)//用于计算Cn/m的函数
{
if(m == i) return 1;
if(m - i < i) i = m - i;
double x = 1.0,y = 1.0;
for(int j = 1;j <= i;j ++)
{
x *= (m - j + 1);
y *= j;
}
return x / y;
}
double fun(int m)//用于计算二项展开式
{
double res = 0;
for(int i = m;i >= 1;i --) res += C(m,i) * x[i];
return res + 1;
}
int main()
{
scanf("%d %d", &n,&k);
while(n --)
{
scanf("%lf", &p);
double res = x[k];
for(int i = k;i >= 1;i --)
{
x[i] = fun(i) * p;
y[i] += x[i];
}
y[k] -= res * p;//减去上次的项与此处概率乘积的结果,维护最后的结果
}
printf("%.1lf",y[k]);
return 0;
}