[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;

}

  

你可能感兴趣的:(IO)