HZOJ 题

首先对于n<=100的点,直接暴力dp,f[i][j][k]表示时间为i,在i,j位置的方案数,枚举转移即可,期望得分40。

 1     if(n<=100)
 2     {
 3         if(t==0)
 4         {
 5             f[0][100][100]=1;
 6             for(int i=1;i<=n;i++)
 7                 for(int x=1;x<=200;x++)
 8                     for(int y=1;y<=200;y++)
 9                         f[i][x][y]=((f[i-1][x-1][y]+f[i-1][x+1][y])%mod+(f[i-1][x][y-1]+f[i-1][x][y+1])%mod)%mod;
10             printf("%d\n",f[n][100][100]);
11             return 0;
12         }
13         if(t==1)
14         {
15             f[0][1][0]=1;
16             for(int i=1;i<=n;i++)
17                 for(int x=1;x<=101;x++)
18                     f[i][x][0]=(f[i-1][x-1][0]+f[i-1][x+1][0])%mod;
19             printf("%d\n",f[n][1][0]);
20             return 0;
21         }
22         if(t==2)
23         {
24             f[0][100][100]=1;
25             for(int i=1;i<=n;i++)
26                 for(int x=1;x<=200;x++)
27                     for(int y=1;y<=200;y++)
28                         if(x==100||y==100)
29                             f[i][x][y]=((f[i-1][x-1][y]+f[i-1][x+1][y])%mod+(f[i-1][x][y-1]+f[i-1][x][y+1])%mod)%mod;
30             printf("%d\n",f[n][100][100]);
31             return 0;
32         }
33         if(t==3)
34         {
35             f[0][1][1]=1;
36             for(int i=1;i<=n;i++)
37                 for(int x=1;x<=n+1;x++)    
38                     for(int y=1;y<=n+1;y++)
39                         f[i][x][y]=((f[i-1][x-1][y]+f[i-1][x+1][y])%mod+(f[i-1][x][y-1]+f[i-1][x][y+1])%mod)%mod;
40             printf("%d\n",f[n][1][1]);
41             return 0;
42         }
43     }
代码实现

type0:这里

type1:显然卡特兰数……

type2:居然是个dp

f[i]表示走了i步回到原点的方案数,枚举第一次回到原点时走过的步数j(为了存在合法解,j为偶数),则此时方案数为f[i-j]*catalan(j/2-1),复杂度为O(n^2)所以最大范围只出到1000.

type3:

枚举横向移动了多少步.横向移动i步时(为了存在合法解,i必须是偶数),方案数为C(n,i)*catalan(i/2)*catalan((n-i)/2)

可以这样考虑:横向移动了i步,因为只能在第一象限,所以横向是一个卡特兰数,同理纵向也是一个卡特兰数。

  1 #include<iostream>
  2 #include<cstring>
  3 #include<cstdio>
  4 #define LL long long
  5 using namespace std;
  6 const int mod=1e9+7;
  7 int n,t;
  8 int f[110][210][210];
  9 LL f1[1100];
 10 LL jc[100010];
 11 LL poww(LL a,int b,int mod)
 12 {
 13     LL ans=1;
 14     while(b)
 15     {
 16         if(b&1)ans=ans*a%mod;
 17         a=a*a%mod;
 18         b=b>>1;
 19     }
 20     return ans;
 21 }
 22 LL C(int n,int m)
 23 {
 24     if(m>n)return 0;
 25     if(!m)return 1;
 26     return jc[n]*poww(jc[m],mod-2,mod)%mod*poww(jc[n-m],mod-2,mod)%mod;
 27 }
 28 LL H(int i)
 29 {
 30     return C(2*i,i)*poww(i+1,mod-2,mod)%mod;
 31 }
 32 inline int read();
 33 signed main()
 34 {    
 35     n=read(),t=read();
 36     if(n<=100)
 37     {
 38         if(t==0)
 39         {
 40             f[0][100][100]=1;
 41             for(int i=1;i<=n;i++)
 42                 for(int x=1;x<=200;x++)
 43                     for(int y=1;y<=200;y++)
 44                         f[i][x][y]=((f[i-1][x-1][y]+f[i-1][x+1][y])%mod+(f[i-1][x][y-1]+f[i-1][x][y+1])%mod)%mod;
 45             printf("%d\n",f[n][100][100]);
 46             return 0;
 47         }
 48         if(t==1)
 49         {
 50             f[0][1][0]=1;
 51             for(int i=1;i<=n;i++)
 52                 for(int x=1;x<=101;x++)
 53                     f[i][x][0]=(f[i-1][x-1][0]+f[i-1][x+1][0])%mod;
 54             printf("%d\n",f[n][1][0]);
 55             return 0;
 56         }
 57         if(t==2)
 58         {
 59             f[0][100][100]=1;
 60             for(int i=1;i<=n;i++)
 61                 for(int x=1;x<=200;x++)
 62                     for(int y=1;y<=200;y++)
 63                         if(x==100||y==100)
 64                             f[i][x][y]=((f[i-1][x-1][y]+f[i-1][x+1][y])%mod+(f[i-1][x][y-1]+f[i-1][x][y+1])%mod)%mod;
 65             printf("%d\n",f[n][100][100]);
 66             return 0;
 67         }
 68         if(t==3)
 69         {
 70             f[0][1][1]=1;
 71             for(int i=1;i<=n;i++)
 72                 for(int x=1;x<=n+1;x++)    
 73                     for(int y=1;y<=n+1;y++)
 74                         f[i][x][y]=((f[i-1][x-1][y]+f[i-1][x+1][y])%mod+(f[i-1][x][y-1]+f[i-1][x][y+1])%mod)%mod;
 75             printf("%d\n",f[n][1][1]);
 76             return 0;
 77         }
 78     }
 79     else
 80     {
 81         LL ans=0;
 82         jc[0]=1;for(int i=1;i<=100000;i++)jc[i]=jc[i-1]*i%mod;
 83         if(t==0)
 84         {
 85             int s,x,z,y;
 86             for(s=0;s<=n/2;s++)
 87             {
 88                 x=s;z=y=(n-s-x)/2;    
 89                 ans=(ans+jc[n]*poww(jc[s],mod-2,mod)%mod*poww(jc[x],mod-2,mod)%mod*poww(jc[z],mod-2,mod)%mod*poww(jc[y],mod-2,mod)%mod)%mod;
 90             }
 91             printf("%lld\n",ans%mod);
 92             return 0;
 93         }
 94         if(t==1)
 95         {
 96             n=n/2;ans=1;
 97             for(int i=n+2;i<=2*n;i++)ans=ans*i%mod;
 98             ans=ans*poww(jc[n],mod-2,mod);
 99             printf("%lld\n",ans%mod);
100             return 0;
101         }
102         if(t==2)
103         {    
104             f1[0]=1;
105             for(int i=2;i<=n;i+=2)
106                 for(int j=2;j<=i;j+=2)
107                     f1[i]=(f1[i]+4*f1[i-j]*H(j/2-1)%mod)%mod;
108             printf("%lld\n",f1[n]%mod);
109             return 0;
110         }
111         if(t==3)
112         {
113             for(int i=0;i<=n;i+=2)
114                 ans=(ans+C(n,i)*H(i/2)%mod*H((n-i)/2)%mod)%mod;
115             printf("%lld\n",ans);
116             return 0;
117         }
118     }
119 }
120 inline int read()
121 {    
122     int s=0;char a=getchar();
123     while(a<'0'||a>'9')a=getchar();
124     while(a>='0'&&a<='9'){s=s*10+a-'0';a=getchar();}
125     return s;
126 }
暴力和正解全在这里!!

 

 

posted @ 2019-07-28 20:46  Al_Ca  阅读(346)  评论(0编辑  收藏  举报
ヾ(≧O≦)〃嗷~