补多校系列,具体见多校题解http://www.cnblogs.com/duoxiao/p/5777700.html
值得注意的是如果当前i初始向左,前i个骑士最终只有1个向右
对于f[i][1]状态的转移为f[i][1]=∑ f[i-1][k]*0.5^(k-1)
因为我们只要比k-1场就可以了,那一个活下来的是骑士i还是前i-1个骑士中的无关紧要
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 typedef long long ll; 5 const int mo=1e9+7; 6 ll f[1010][1010],d[1010]; 7 int a[1010],n; 8 9 ll quick(ll x,int y) 10 { 11 ll s=1; 12 while (y) 13 { 14 if (y&1) s=s*x%mo; 15 x=x*x%mo; 16 y>>=1; 17 } 18 return s; 19 } 20 21 int main() 22 { 23 int cas; 24 scanf("%d",&cas); 25 d[0]=1; d[1]=quick(2,mo-2); 26 for (int i=2; i<=1000; i++) d[i]=d[i-1]*d[1]%mo; 27 for (int tt=1; tt<=cas; tt++) 28 { 29 scanf("%d",&n); 30 for (int i=1; i<=n; i++) scanf("%d",&a[i]); 31 printf("Case #%d: ",tt); 32 if (n==1) 33 { 34 puts("1"); 35 continue; 36 } 37 memset(f,0,sizeof(f)); 38 f[1][1]=1; 39 for (int i=2; i<n; i++) 40 if (a[i]) 41 { 42 for (int j=1; j<=i; j++) 43 f[i][j]=f[i-1][j-1]; 44 } 45 else { 46 for (int j=i-1; j>=2; j--) 47 f[i][j]=(f[i-1][j]+f[i][j+1])*d[1]%mo; 48 for (int j=1; j<=i-1; j++) 49 f[i][1]=(f[i][1]+f[i-1][j]*d[j-1]%mo)%mo; 50 } 51 ll ans=0; 52 for (int i=1; i<n; i++) 53 ans=(ans+f[n-1][i]*d[i]%mo)%mo; 54 printf("%lld\n",ans); 55 } 56 }
时间: 2024-10-25 07:52:23