棋盘型动态规划 之 CODE[VS] 1010 过河卒 2002年NOIP全国联赛普及组
2015-11-03 16:56
375 查看
/* dp[i][j] := 从起点[0][0]到坐标为[i][j]的位置,路径的条数。 卒行走规则:可以向下、或者向右,故 dp[i][j] = dp[i-1][j] + dp[i][j-1] (向下) (向右) 注意: 去掉对方马的控制点 附: codevs测试数据有些弱,可以考虑到这里评测一下:清橙 (主要区别在于,dp[][]数据类型设为long long) */
#include <iostream> #include <cstdlib> #include <cstdio> #include <cstddef> #include <iterator> #include <algorithm> #include <locale> #include <cmath> #include <vector> #include <cstring> using namespace std; const int INF = 0x3f3f3f3f; const int MaxN = 30; const int MaxM = 30; const int MaxAvoid = 9; int n, m, x, y; bool arr[MaxN][MaxM]; long long dp[MaxN][MaxM]; int avoidX[MaxAvoid] = {0, -1, -2, -2, -1, 1, 2, 2, 1}; int avoidY[MaxAvoid] = {0, -2, -1, 1, 2, 2, 1, -1, -2}; void Solve() { if (!arr[0][0]) { // dp 初始化 dp[0][0] = 1; } for (int i = 0; i <= n; ++i) { for (int j = 0; j <= m; ++j) { if (!arr[i][j]) { if ((i - 1) >= 0) dp[i][j] += dp[i - 1][j]; if ((j - 1) >= 0) dp[i][j] += dp[i][j - 1]; } } } cout << dp [m] << endl; } int main() { cin >> n >> m >> x >> y; memset(arr, 0, sizeof(arr)); memset(dp, 0, sizeof(dp)); //去掉对方马的控制点 for (int i = 0; i < MaxAvoid; ++i) { int tx = x + avoidX[i]; int ty = y + avoidY[i]; if ((tx >= 0) && (tx <= n) && (ty >= 0) && (ty <= m)) { arr[tx][ty] = true; } } Solve(); #ifdef HOME cerr << "Time elapsed: " << clock() / CLOCKS_PER_SEC << " ms" << endl; #endif return 0; }