蓝桥杯-地宫取宝

这是一个dp题,可以用4维数据来表示所有的状态。
但是有一个需要注意的点,一般来说,对于每个坐标,有拿跟不拿两种情况,如果没有拿任务宝物的状态表示为0,那么拿取了价值为0的宝物时,要以另一种情况来跟没拿区分。 处理的方法就是将所有宝物的价格+1。

long long dp[55][55][15][15];
constexpr int mod = 1e9 + 7;
void solve(){
    memset(dp, 0ll, sizeof(dp));
    int n, m, k;
    cin >> n >> m >> k;

    vector<vector<int>> grid(n, vector<int>(m));
    for (int i = 0; i < n; ++i){
        for (int j = 0; j < m; ++j){
            cin >> grid[i][j];
            grid[i][j] ++;
        }
    }

    dp[0][0][1][grid[0][0]] = 1;
    dp[0][0][0][0] = 1;
    for (int i = 0; i < n; ++i){
        for (int j = 0; j < m; ++j){
            if (!i && !j){
                continue;
            }
            int cur = grid[i][j];
            if (i){
                for (int u = 0; u <= k; ++u){
                    for (int v = 0; v <= 15; ++v){
                        dp[i][j][u][v] = dp[i - 1][j][u][v];
                    }
                }
                for (int u = 1; u <= k; ++u){
                    for (int v = 0; v < cur; ++v){
                        dp[i][j][u][cur] += dp[i - 1][j][u - 1][v];
                    }
                    dp[i][j][u][cur] %= mod;
                }
            }
            if (j){
                for (int u = 0; u <= k; ++u){
                    for (int v = 0; v <= 15; ++v){
                        dp[i][j][u][v] += dp[i][j - 1][u][v];
                    }
                }
                for (int u = 1; u <= k; ++u){
                    for (int v = 0; v < cur; ++v){
                        dp[i][j][u][cur] += dp[i][j - 1][u - 1][v];
                    }
                    dp[i][j][u][cur] %= mod;
                }
            }
        }
    }

    long long ans = 0;
    for (int u = 0; u <= 12; ++u){
        ans = (ans + dp[n - 1][m - 1][k][u]) % mod;
    }

    cout << ans << endl;
}

//题目不难,但是没注意到这种价值为0的情况,少见!!

posted @ 2024-03-09 22:21  _Yxc  阅读(9)  评论(0编辑  收藏  举报