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 }
波澜前,面不惊。