棋盘型动态规划 之 CODE[VS] 1010 过河卒 2002年NOIP全国联赛普及组

/*
dp[i][j] := 从起点[0][0]到坐标为[i][j]的位置,路径的条数。
 
卒行走规则:可以向下、或者向右,故
dp[i][j] = dp[i-1][j] + dp[i][j-1]
            (向下)      (向右)
 
注意:
去掉对方马的控制点
 
附:
codevs测试数据有些弱,可以考虑到这里评测一下:清橙
(主要区别在于,dp[][]数据类型设为long long)
*/
 1 #include <iostream>
 2 #include <cstdlib>
 3 #include <cstdio>
 4 #include <cstddef>
 5 #include <iterator>
 6 #include <algorithm>
 7 #include <locale>
 8 #include <cmath>
 9 #include <vector>
10 #include <cstring>
11 using namespace std;
12 const int INF = 0x3f3f3f3f;
13 const int MaxN = 30;
14 const int MaxM = 30;
15 const int MaxAvoid = 9;
16 
17 int n, m, x, y;
18 bool arr[MaxN][MaxM];
19 long long dp[MaxN][MaxM];
20 int avoidX[MaxAvoid] = {0, -1, -2, -2, -1, 1, 2,  2,  1};
21 int avoidY[MaxAvoid] = {0, -2, -1,  1,  2, 2, 1, -1, -2};
22 
23 
24 void Solve()
25 {
26     if (!arr[0][0])
27     {
28         // dp 初始化
29         dp[0][0] = 1;
30     }
31     for (int i = 0; i <= n; ++i)
32     {
33         for (int j = 0; j <= m; ++j)
34         {
35             if (!arr[i][j])
36             {
37                 if ((i - 1) >= 0) dp[i][j] += dp[i - 1][j];
38                 if ((j - 1) >= 0) dp[i][j] += dp[i][j - 1];
39             } 
40         }
41     }
42     cout << dp[n][m] << endl;
43 }
44 
45 int main() 
46 {
47 
48     cin >> n >> m >> x >> y;
49     memset(arr, 0, sizeof(arr));
50     memset(dp, 0, sizeof(dp));
51     //去掉对方马的控制点
52     for (int i = 0; i < MaxAvoid; ++i)
53     {
54         int tx = x + avoidX[i];
55         int ty = y + avoidY[i];
56         if ((tx >= 0) && (tx <= n) && (ty >= 0) && (ty <= m))
57         {
58             arr[tx][ty] = true;
59         }
60     }
61     Solve();
62 
63     
64 #ifdef HOME
65     cerr << "Time elapsed: " << clock() / CLOCKS_PER_SEC << " ms" << endl;
66 #endif
67     return 0;
68 }

 

 
posted @ 2015-11-03 16:56  JmingS  阅读(235)  评论(0编辑  收藏  举报