遞推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 #include <iostream> 13 #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點的路徑條數是:"<<dp[r][c]<<endl; 87 return 0; 88 }