1314:【例3.6】过河卒(Noip2002)
下面是常规的代码,过当然是不能过的。
之所以放上来是因为它好歹也是个看的过去的常规搜索递归程序(可惜没找到改成尾递归的方法o(╥﹏╥)o)
1 #include<iostream> 2 using namespace std; 3 int n,m,ans,x[9],y[9]; 4 5 bool check(int a,int b){ 6 if(a>n||b>m)return 0; 7 for(int i=0;i<9;i++){ 8 if(a==x[i]&&b==y[i])return 0; 9 } 10 return 1; 11 } 12 void getPath(int x,int y){ 13 if(x==n&&y==m){ 14 ans++; 15 return; 16 } 17 if(check(x+1,y))getPath(x+1,y); 18 if(check(x,y+1))getPath(x,y+1); 19 } 20 int main(){ 21 22 cin>>n>>m>>x[0]>>y[0]; 23 //得到马所影响的九个位置 24 x[1]=x[4]=x[0]-1,x[2]=x[3]=x[0]-2; 25 x[5]=x[8]=x[0]+1,x[6]=x[7]=x[0]+2; 26 y[1]=y[8]=y[0]+2,y[2]=y[7]=y[0]+1; 27 y[3]=y[6]=y[0]-1,y[4]=y[5]=y[0]-2; 28 //核心算法 29 getPath(0,0); 30 cout<<ans; 31 return 0; 32 }
下面才是正文,别问,问就是递推≈动态规划
注意下面两点:
- 初始化时遇到“断点”应及时break,因为前路断了,后路也不可能有
- 最后的结果需要用long long来接收
1 #include<iostream> 2 using namespace std; 3 typedef long long ll; 4 int n,m,x[9],y[9]; 5 ll a[25][25]; 6 7 bool check(int a,int b){ 8 for(int i=0;i<9;i++){ 9 if(a==x[i]&&b==y[i])return 0; 10 } 11 return 1; 12 } 13 void init(){ 14 x[1]=x[4]=x[0]-1,x[2]=x[3]=x[0]-2; 15 x[5]=x[8]=x[0]+1,x[6]=x[7]=x[0]+2; 16 y[1]=y[8]=y[0]+2,y[2]=y[7]=y[0]+1; 17 y[3]=y[6]=y[0]-1,y[4]=y[5]=y[0]-2; 18 for(int i=0;i<=m;i++) 19 if(check(0,i))a[0][i]=1; 20 else break; 21 for(int i=0;i<=n;i++){ 22 if(check(i,0))a[i][0]=1; 23 else break; 24 } 25 } 26 int main(){ 27 cin>>n>>m>>x[0]>>y[0]; 28 init(); 29 for(int i=1;i<=n;i++){ 30 for(int j=1;j<=m;j++){ 31 if(check(i,j)) a[i][j]=a[i-1][j]+a[i][j-1]; 32 else a[i][j]=0; 33 } 34 } 35 cout<<a[n][m]; 36 return 0; 37 }