【QQQ】codevsスキーと記憶化検索の小さな経験


私を突いて←
テーマ説明Description
trsはスキーが好きです.彼は矩形のスキー場に来た.このスキー場は簡単にするために、r行c列の行列で各地形を表した.より速い速度を得るためには、滑走路を下に傾けなければならない.例えば、サンプルの矩形は、ある点から上下左右の4つの隣接する点の1つにスライドすることができる.例えば24-17-16-1で、実は25-24-23...3-2-1がもっと長く、実際にはこれが一番長いです.
入力記述Input Description
入力ファイル
1行目:2つの数字r,c(1<=r,c<=100)は、行列の行列を表す.2.r+1行:各行c個数で、この行列を表す.
出力記述Output Description
出力ファイル
1行のみ:1つの整数を出力し、スライド可能な最大長を表します.
サンプル入力Sample Input
5 5 1 2 3 4 5 16 17 18 19 6 15 24 25 20 7 14 23 22 21 8 13 12 11 10 9
サンプル出力Sample Output
25
初めて手を打って列の広い捜索をして、意外にもAは4つの点を打ってへっへっへっへっへっへっへっへっへっへっへっへっへっへっへっへっ
orz 57級wzdとwyhの2人のDPの大物
最初の記憶化検索のテーマ.
構想は各点を起点としてdfsを行い,dp配列で毎回検索される最長路を記録する.
最初はバカに違うスタート地点で見つけたポイントごとに一番長い道は違うQAAQだと思っていました
まあ、再帰は同じ過程を一つ一つ計算していくことです
最初に最適解が要求される以上,プログラムで得られる各層の結果も必ず最適である.
そこまで滑って急に転覆したとしても、滑った最長の経路は何ですか23333
このように、ノードを検索して、彼の最も長い道が検索されたことを発見したら、直接呼び出します.
転覆する前に最大でどのくらい滑ることができることを知っていて、起きて引き続き滑って更にどのくらい滑ることができます23333
#include
#include
using namespace std;
const int MAXN = 1000 + 1;
int map[MAXN][MAXN],dp[MAXN][MAXN],maxx;
int mu[] = {0,-1,1,0},
    mr[] = {1,0,0,-1};
int dfs(int k,int j)
{
    if(dp[k][j]) return dp[k][j];
    int ans = 1;
    for(int i = 0; i < 4; i ++)
    {
        int x = k + mu[i] ;
        int y = j + mr[i] ;
        if(map[x][y] > map[k][j])
            ans = max(ans, dfs(x, y) + 1);
    }
    return dp[k][j] = ans;
}
int m,n;
int main()
{
    cin >> m >> n;
    for(int i = 1; i <= m; i ++)
        for(int j = 1; j <= n;j ++)
            cin >> map[i][j];
    for(int i = 1; i <= m; i ++)
        for(int j = 1; j <= n;j ++)
        {
            dp[i][j] = max(dfs(i,j),dp[i][j]);
            maxx = max(maxx, dp[i][j]);
        }
    cout << maxx;
    return 0;
}