棋盘型动态规划。(PPT:http://wenku.baidu.com/view/56badad850e2524de5187ea3.html)该类动态规划有一个共性,那就是在一个矩阵中(一般是二维矩阵,当然可能有更加复杂的图形)给出一些规则,然后按规则去做某些决策,我们思考这类问题的基本方法是:以坐标为状态,坐标之间的转换关系,一般利用问题给出的规则进行决策转移。
状态转移方程一般可描述如下:
F(i,j)=Max{f(i-1,k)}+决策;这里k为规则数
此题简单。唯一的处理是用(不会重复的)整数来记录二维的点。还有差点忘记了C++中的数组定义是int mx[25][25]这样的了。多语言使用的伤。
#include <iostream> #include <climits> #include <cstring> #include <set> using namespace std; void tryForbid(int x, int y, int n, int m, set<int> &fset) { if (x >= 0 && y >=0 && x <= n && y <= m) { fset.insert(x*25+y); } } int mx[25][25]; int main() { int n, m; cin >> n >> m; int x, y; cin >> x >> y; memset(mx, 0, sizeof(mx)); set<int> fset; tryForbid(x, y, n, m, fset); tryForbid(x+1, y-2, n, m, fset); tryForbid(x+2, y-1, n, m, fset); tryForbid(x+2, y+1, n, m, fset); tryForbid(x+1, y+2, n, m, fset); tryForbid(x-1, y+2, n, m, fset); tryForbid(x-2, y+1, n, m, fset); tryForbid(x-2, y-1, n, m, fset); tryForbid(x-1, y-2, n, m, fset); for (int i = 0; i <= n; i++) { for (int j = 0; j <= m; j++) { if (i == 0 && j == 0) mx[i][j] = 1; else if (fset.count(i*25+j)>0) mx[i][j] = 0; else if (i == 0) mx[i][j] = mx[i][j-1]; else if (j == 0) mx[i][j] = mx[i-1][j]; else { mx[i][j] = mx[i-1][j] + mx[i][j-1]; } } } cout << mx[n][m]; return 0; }