递推2--过河卒(Noip2002)
一、心得
写出递推公式就OK了,具体编程还是很简单的
二、题目及分析
过河卒(NOIp2002)
【问题描述】
棋盘上A点有一个过河卒,需要走到目标B点。卒行走的规则:可以向下、或者向右。同时在棋盘上C点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此称之为“马拦过河卒”。
棋盘用坐标表示,A点(0, 0)、B点(n, m),(n, m为不超过20的整数),同样马的位置坐标是需要给出的。C≠A且C≠B。现在要求你计算出卒从A点能够到达B点的路径的条数,假设马的位置是固定不动的,并不是卒走一步马走一步。
三、代码及结果
这里取起点:A(0,0) 终点:B(4,8) 马的位置:C(2,4)
1 /* 2 过河卒问题 3 f[r][c]表示到达(r,c)位置的路径条数 4 只能从上面来或者从左边来 5 f[r][c]=从上面一行来+从左边一列来 6 f[r][c]=f[r-1][c]+f[r][c-1] 7 如果这点被马控制,那么: 8 f[r][c]=0; 9 所以从上往下,从左往右依次递推就好了 10 那些边界都为0,且f[0][0]=1 11 */ 12 #include13 #define Max 25 14 using namespace std; 15 //r在前c在后 16 int horseControl[9][2]={{0,0},{-2,1},{-1,2},{1,2},{2,1},{2,-1},{1,-2},{-1,-2},{-2,-1}}; 17 int dp[Max][Max];//f[r][c]表示到达(r,c)位置的路径条数 18 int horse[Max][Max];//判断该点是否被马控制 19 20 // 初始化马的控制点 21 void initHorseControl(int r,int c){//马的坐标需要被传进来 22 horse[Max][Max]={0};//对house初始化为0 23 for(int i=0;i<9;i++){ 24 int r1=r+horseControl[i][0]; 25 int c1=c+horseControl[i][1]; 26 if(r1>=0&&c1>=0){ 27 horse[r1][c1]=1; 28 } 29 } 30 } 31 32 //显示数组中的内容 33 void showArray(int x,int y,int a[Max][Max]){ 34 for(int i=0;i<=x;i++){ 35 for(int j=0;j<=y;j++){ 36 printf("%5d ",a[i][j]); 37 } 38 printf("\n"); 39 } 40 } 41 42 // 初始化棋盘 43 void initChessboard(int r,int c){ 44 for(int i=0;i<=r;i++){//对列进行初始化 45 dp[i][0]=0; 46 } 47 for(int j=0;j<=c;j++){ 48 dp[0][j]=0; 49 } 50 dp[0][1]=1; 51 } 52 53 //递推操作 54 void dpOperation(int r,int c){ 55 for(int i=1;i<=r;i++){ 56 for(int j=1;j<=c;j++){ 57 if(horse[i][j]==1){//表示被马控制 58 dp[i][j]=0; 59 } 60 else{ 61 dp[i][j]=dp[i-1][j]+dp[i][j-1]; 62 } 63 } 64 } 65 } 66 67 int main(){ 68 //是要算题中4,8的,但是我们存储的是线,有行5条,列9条 69 // 70 int r=5,c=9;//格子行和列,也就是目的点的坐标 71 int x=3,y=5;//马所在的点 72 cout<<"起点:A(0,0) 终点:B(4,8) 马的位置:C(2,4)"<<endl; 73 initHorseControl(x,y);// 初始化马的控制点 74 cout<<"---------------------------------------------------------------------"<<endl; 75 cout<<"马控制的点:"<<endl; 76 showArray(r,c,horse); 77 cout<<"---------------------------------------------------------------------"<<endl; 78 initChessboard(r,c);// 初始化棋盘 79 cout<<"初始化的棋盘:"<<endl; 80 showArray(r,c,dp); 81 cout<<"---------------------------------------------------------------------"<<endl; 82 dpOperation(r,c);//递推操作 83 cout<<"进行了路径计算后的棋盘:"<<endl; 84 showArray(r,c,dp); 85 cout<<"---------------------------------------------------------------------"<<endl; 86 cout<<"A点到B点的路径条数是:"< endl; 87 return 0; 88 }