补多校系列,具体见多校题解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 }
View Code

 

posted on 2017-02-12 17:52  acphile  阅读(242)  评论(0编辑  收藏  举报