题目
一个棋盘,在起点 ( 1 , 1 ) (1,1) (1,1)有一匹马,只能向右走马步,问到达 ( m , n ) (m,n) (m,n)可以有多少条路径?
分析
PS:ssl 1289 还有障碍(kind of easy)
设
f
[
i
]
[
j
]
f[i][j]
f[i][j]表示到达
(
i
,
j
)
(i,j)
(i,j)可以有多少条路径
可得
f
[
i
+
2
]
[
j
+
1
]
+
=
f
[
i
]
[
j
]
;
f[i+2][j+1]+=f[i][j];
f[i+2][j+1]+=f[i][j];
f
[
i
+
2
]
[
j
−
1
]
+
=
f
[
i
]
[
j
]
;
f[i+2][j-1]+=f[i][j];
f[i+2][j−1]+=f[i][j];
f
[
i
+
1
]
[
j
+
2
]
+
=
f
[
i
]
[
j
]
;
f[i+1][j+2]+=f[i][j];
f[i+1][j+2]+=f[i][j];
f
[
i
+
1
]
[
j
−
2
]
+
=
f
[
i
]
[
j
]
;
f[i+1][j-2]+=f[i][j];
f[i+1][j−2]+=f[i][j];
高精度我就不多说了
代码(压14位高精度)
#include <cstdio>
using namespace std;
typedef long long ll;
ll max(ll a,ll b){return (a>b)?a:b;}
void wriii(ll ans){
if (ans>9) wriii(ans/10);
putchar(ans%10+48);
}
struct rec{
ll a[4];
void add(rec x){
rec tmp=*this; ll g=0;
tmp.a[0]=max(a[0],x.a[0]);
for (ll i=1;i<=tmp.a[0];i++){
tmp.a[i]+=x.a[i]+g;
g=tmp.a[i]/1000000000000ll;
tmp.a[i]%=1000000000000ll;
}
if (g) tmp.a[++tmp.a[0]]=g;
*this=tmp;
}
void print(){
for (ll i=a[0];i>0;i--)
{
if(i!=a[0])
{
ll k=1e11;
while(a[i]<k&&k>9) putchar(48),k/=10;
}
wriii(a[i]);
}
}
}f[103][103];
ll n,m;
int main(){
scanf("%lld%lld",&m,&n);
f[1][1].a[++f[1][1].a[0]]=1ll;
for (ll i=1;i<=n;i++)
for (ll j=1;j<=m;j++)
if (f[i][j].a[0]){
if (i<n-1&&j<m) f[i+2][j+1].add(f[i][j]);
if (i<n-1&&j>1) f[i+2][j-1].add(f[i][j]);
if (i<n&&j<m-1) f[i+1][j+2].add(f[i][j]);
if (i<n&&j>2) f[i+1][j-2].add(f[i][j]);
}
f[n][m].print();
return 0;
}