NC14383. 01序列
描述
给定长度为 n 的01序列,序列中部分位置已经确定,剩余部分01等概率出现。对最终序列求最长不下降序列(如有多种可能序列,则在此基础上最大化1的个数),设最长不下降序列的长度为 len,最长不下降序列中1的个数为 num,求期望 E(len * num) * 2 ^ 10000 对 1000000007 取模的结果。
输入描述
第一行包括一个正整数 n(1 <= n <= 1000).
第二行包括 n 个数 a[i](a[i]∈{-1, 0, 1}),a[i] 等于-1表示数列此位置未确定,a[i] 等于0和1表示数列此位置已确定为a[i] .
输出描述
一行,即所求答案.
示例1
输入:
5 1 1 1 0 -1
输出:
820147489
C++(clang++11) 解法, 执行用时: 37ms, 内存消耗: 29440K, 提交时间: 2021-02-11 14:29:16
#include<bits/stdc++.h> #define LL long long using namespace std; const int INF=1e9; const int N=1e3+100; const LL P=1000000007; int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } void print(LL x){ if(x>9) print(x/10); putchar(x%10+'0'); } void pls(LL &x,LL y){ x+=y;if(x>=P)x-=P; } int n; int a[N]; LL len[N][N],num[N][N],cnt[N][N],dp[N][N]; int main(){ int tt=10000; n=read(); for(int i=1;i<=n;++i) a[i]=read(); cnt[0][0]=1; for(int i=0;i<n;++i){ if(a[i+1]==-1) --tt; for(int j=0;j<=i;++j){ if(a[i+1]!=1){ if(j>0) { pls(len[i+1][j-1],len[i][j]); pls(cnt[i+1][j-1],cnt[i][j]); pls(num[i+1][j-1],num[i][j]); pls(dp[i+1][j-1],dp[i][j]); } else{ pls(len[i+1][j],(cnt[i][j]+len[i][j])%P); pls(cnt[i+1][j],cnt[i][j]); } } if(a[i+1]!=0){ pls(len[i+1][j+1],(cnt[i][j]+len[i][j])%P); pls(cnt[i+1][j+1],cnt[i][j]); pls(num[i+1][j+1],(num[i][j]+cnt[i][j])%P); pls(dp[i+1][j+1],(dp[i][j]+num[i][j]+len[i][j]+cnt[i][j])%P); } } } LL ans=0; for(int i=0;i<=n;++i) pls(ans,dp[n][i]); ans=(ans%P+P)%P; for(int i=1;i<=tt;++i) pls(ans,ans); printf("%lld\n",ans); return 0; }