1 条题解

  • 0
    @ 2026-2-17 23:46:22
    #include <iostream>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    // 棋盘最大尺寸,适配n,m≤100的要求
    const int MAXN = 105;
    int grid[MAXN][MAXN]; // 存储生成的矩阵
    int dp[MAXN][MAXN];   // 记忆化数组,dp[i][j]表示以(i,j)为终点的最大路径和
    int n, m;              // 矩阵的行数n、列数m
    // 四个移动方向:上、下、左、右
    int dx[] = {-1, 1, 0, 0};
    int dy[] = {0, 0, -1, 1};
    
    // 记忆化DFS:返回以(x,y)为终点的最大路径和
    int dfs(int x, int y)
    {
        // 已经计算过,直接返回缓存的结果
        if (dp[x][y] != -1)
        {
            return dp[x][y];
        }
    
        int max_prev = 0; // 相邻合法格子的最大dp值,初始为0(无合法相邻格子时)
        // 遍历四个方向
        for (int i = 0; i < 4; i++)
        {
            int nx = x + dx[i];
            int ny = y + dy[i];
            // 合法性校验:坐标在边界内,且相邻格子的数字更小
            if (nx >= 1 && nx <= n && ny >= 1 && ny <= m && grid[nx][ny] < grid[x][y])
            {
                max_prev = max(max_prev, dfs(nx, ny));
            }
        }
    
        // 计算当前格子的dp值并缓存
        dp[x][y] = grid[x][y] + max_prev;
        return dp[x][y];
    }
    
    int main()
    {
        int s;
        // 输入矩阵大小和初始种子s
        cin >> n >> m >> s;
    
        // 按照题目算法生成矩阵
        for (int i = 1; i <= n; i++)
        {
            for (int j = 1; j <= m; j++)
            {
                // 用long long避免乘法溢出
                s = (long long)s * 345 % 19997;
                grid[i][j] = (s % 10) + 1;
            }
        }
    
        // 初始化记忆化数组为-1,表示未计算
        memset(dp, -1, sizeof(dp));
    
        int ans = 0;
        // 遍历所有格子,找到最大的路径和
        for (int i = 1; i <= n; i++)
        {
            for (int j = 1; j <= m; j++)
            {
                ans = max(ans, dfs(i, j));
            }
        }
    
        // 输出结果
        cout << ans << endl;
    
        return 0;
    }
    
    • 1

    信息

    ID
    1288
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者