宾馆租期到了,早上打理了一下宿舍的事儿。
下午很难受的暴零了,大佬做出来个区间dp,我现学了期望dp,然后写了个期望dp超时了,要是m变成原来的一半就过了,正好卡死了,然后搞了一发假dp,还是不是很理解区间dp,所以失败了。
#include<iostream>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<algorithm>
#define mo 1000000007
using
namespace
std;
long
long
a[1010];
long
long
b[1010];
long
long
p[1010];
long
long
ip[1010];
long
long
l[1010][1010];
long
long
ans[1010];
long
long
qpow(
long
long
x,
long
long
y){
long
long
ans=1;
long
long
k=x;
while
(y){
if
(y&1)ans=ans*k%mo;
k=k*k%mo;
y>>=1;
}
return
(ans+mo)%mo;
}
void
get(){
long
long
i;
a[0]=1;
b[0]=1;
a[1]=1;
b[1]=1;
for
(i=2;i<1010;i++){
a[i]=((a[i-1]*i)%mo+mo)%mo;
b[i]=(qpow(a[i],mo-2)+mo)%mo;
}
}
long
long
zuhe(
long
long
n,
long
long
m){
if
(n<m||m<0)
return
0;
return
a[n]*b[m]%mo*b[n-m]%mo;
}
int
main(){
long
long
n,m;
long
long
i,j,k;
get();
while
(
scanf
(
"%lld%lld"
,&n,&m)!=EOF){
long
long
temp=qpow(100,mo-2);
for
(i=1;i<=n;i++){
scanf
(
"%lld"
,&p[i]);
p[i]=p[i]*temp%mo;
for
(j=1;j<=m-1;j++){
l[i][j]=(l[i-1][j]+1)%mo;
for
(k=1;k<=j-1;k++){
l[i][j]=(l[i][j]+zuhe(j,k)*l[i-1][k]%mo)%mo;
}
l[i][j]=l[i][j]*p[i]%mo;
}
long
long
temp=1;
for
(j=1;j<=m-1;j++){
temp=(temp+zuhe(m,j)*l[i-1][j]%mo)%mo;
}
ans[i]=(ans[i-1]+p[i]*temp%mo)%mo;
}
printf
(
"%lld\n"
,(ans[n]+mo)%mo);
}
}
而正解相当于对区间的一个枚举,对每个区间为全1的情况进行了一个概率枚举,就相当于里面全都为1,两头为0的情况,一开始有点这个想法,但总觉的这样会有重复,这个操作可有够厉害的。