【题目描述】
有
n
个数字,每一个数字可能为
【输入格式】
第一行,三个整数n, m, k
第二行,m个整数表示wt�� , … , ������
【输出格式】
输出值期望对1000000007取模的值。
【样例输入】
2 2 2
1 2
【样例输出】
750000007
【解题报告】
NOIP模拟的一道题,感觉比较有意思。
首先我们来处理一个简单的问题
问题1:有n个数,每个数的范围在
1—m
中随机取,问这
n
个数最大值的期望?
解法:最大值的期望?听起来很懵逼。。
我们把这个期望值记为
现在我们知道当每一个k值作为最大值的概率了,现在让我们回到期望的定义:离散型随机变量X的取值为
x1,x2,x3,x4...
,
p1,p2,p3,p4...
为
X
对应取值的概率,可理解为数据
所以说我们很轻松的得出了
X(n)=∑(k=1,k<=m)k∗P(k)
问题2:有n个数,每个数的范围在
1—m
中随机取,每个数值有一个代价
w(i)
,问这
n
个数最大值
解法:现在的问题比问题1多了一个
w(i)
,但是如果理解了期望的定义,看懂了问题1的思路。
所以我们很轻松地得出了
X(n)=∑(k=1,k<=m)w(k)∗P(k)
问题3:原问题。
这k个选择是互不影响的,所以说答案为:
X(n)=∑(k=1,k<=m)w(k)∗P(k)
ans=(n−k+1)∗X(k)
代码如下:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define mod 1000000007
#define N 510
int n,m,k,M=1;
int w[N],p[N];
int ans=0;
int mpow(int a,int b)
{
int ans=1,base=a;
while(b!=0)
{
if(b&1!=0) ans=1LL*ans*base%mod;
base=1LL*base*base%mod;
b>>=1;
}
return ans%mod;
}
int main()
{
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=m;++i) scanf("%d",&w[i]);
for(int i=1;i<=m;++i) p[i]=mpow(i,k);
int inv=mpow(p[m],mod-2);
for(int i=1;i<=m;++i)
{
int tmp=1LL*w[i]*(p[i]-p[i-1]+mod)%mod*inv%mod;
ans=(ans+tmp)%mod;
}
printf("%d\n",1LL*ans*(n-k+1)%mod);
return 0;
}