UVa 926【简单dp,递推】

UVa 926

题意:给定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 }
原文地址:https://www.cnblogs.com/zxhyxiao/p/7380295.html