[wikioi]过河卒

棋盘型动态规划。(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;
}

  

原文地址:https://www.cnblogs.com/lautsie/p/3329909.html