2018年8月16日暑假训练日记

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/m0_37772713/article/details/81744119

  宾馆租期到了,早上打理了一下宿舍的事儿。

  下午很难受的暴零了,大佬做出来个区间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的情况,一开始有点这个想法,但总觉的这样会有重复,这个操作可有够厉害的。

猜你喜欢

转载自blog.csdn.net/m0_37772713/article/details/81744119