UVa 926【简单dp,递推】
题意:给定N*N的街道图和起始点,有些街道不能走,问从起点到终点有多少种走法。
很基础的dp、递推,但是有两个地方需要注意,在标记当前点某个方向不能走时,也要同时标记对应方向上的对应点。另一点就是要开long long存。要是不考虑障碍的话,按组合数算从(1,1)走到(n,n)需要2*n步,东、北方向各走n步,结果就是C(n/2,n),这个结果会很大!!!
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 typedef long long ll; 6 const int N = 35; 7 ll dp[N][N]; 8 int g[N][N][5]; 9 int n, m, sx, sy, ex, ey; 10 11 int main() 12 { 13 int C; 14 cin >> C; 15 while (C--) 16 { 17 memset(dp, 0, sizeof(dp)); 18 memset(g, 0, sizeof(g)); 19 cin >> n >> sx >> sy >> ex >> ey >> m; 20 int a, b; 21 while (m--) 22 { 23 cin >> a >> b; 24 char c; 25 scanf(" %c", &c); 26 if (c == 'N') g[a][b][1] = 1, g[a][b + 1][3] = 1; 27 else if (c == 'W') g[a][b][2] = 1, g[a - 1][b][4] = 1; 28 else if (c == 'S') g[a][b][3] = 1, g[a][b - 1][1] = 1; 29 else g[a][b][4] = 1, g[a + 1][b][2] = 1; 30 } 31 dp[sx][sy] = 1; 32 for (int i = sx; i <= ex; i++) { 33 for (int j = sy; j <= ey; j++) 34 { 35 if (!g[i][j][2]) dp[i][j] += dp[i - 1][j]; 36 if (!g[i][j][3]) dp[i][j] += dp[i][j - 1]; 37 } 38 } 39 cout << dp[ex][ey] << endl; 40 } 41 return 0; 42 }