洛谷 P1002 過河卒(一維dp)
阿新 • • 發佈:2018-11-23
題目描述
棋盤上 AA 點有一個過河卒,需要走到目標 BB 點。卒行走的規則:可以向下、或者向右。同時在棋盤上 CC 點有一個對方的馬,該馬所在的點和所有跳躍一步可達的點稱為對方馬的控制點。因此稱之為“馬攔過河卒”。
棋盤用座標表示, AA 點 (0, 0)(0,0) 、 BB 點 (n, m)(n,m) ( nn , mm 為不超過 2020 的整數),同樣馬的位置座標是需要給出的。
現在要求你計算出卒從 AA 點能夠到達 BB 點的路徑的條數,假設馬的位置是固定不動的,並不是卒走一步馬走一步。
輸入輸出格式
輸入格式:
一行四個資料,分別表示 BB 點座標和馬的座標。
輸出格式:
一個數據,表示所有的路徑條數。
輸入輸出樣例
輸入樣例#1: 複製
6 6 3 3
輸出樣例#1: 複製
6
說明
結果可能很大!
剛開始用dfs做的,直接TLE,看了題解才發現是線性dp,因為當前狀態只取決於dp[i-1][j]和dp[i][j-1],兩者相加就行,然後就是馬的位置控制,我沒下過象棋不知道橫的“日”也可以,卡了許久,百度了才知道,著實是很慚愧
#include <iostream> #include <string.h> #include <algorithm> using namespace std; long long dp[25][25],map[25][25]; void mark(int x,int y) { map[x][y]=1; map[x+1][y+2]=1; map[x-1][y-2]=1; map[x+1][y-2]=1; map[x-1][y+2]=1; map[x+2][y+1]=1; map[x-2][y-1]=1; map[x-2][y+1]=1; map[x+2][y-1]=1; } int main() { int n,m,hx,hy,i,j,k; while(cin>>n>>m>>hx>>hy) { memset(map,0,sizeof(map)); mark(hx,hy);//標記馬的控制位置 dp[0][0]=1; for(i=0;i<=n;i++) { for(j=0;j<=m;j++) { if(j==0 && i!=0)//防止越界 { dp[i][j]=dp[i-1][j]; } else if(i==0 && j!=0) { dp[i][j]=dp[i][j-1]; } else if(i==0 && j==0); else { dp[i][j]=dp[i-1][j]+dp[i][j-1]; } if(map[i][j]) dp[i][j]=0;//如果是馬控制點,直接清空這個點 } } cout<<dp[n][m]<<endl; } return 0; }