avatar
fireworks99
keep hungry keep foolish

SDNU 1032 1194 1422 四维DP

Description

两枚棋子从(1, 1)走到(m,n),只能向下或向右走,不能走同一格

求路径上权值和的最大值。 (1, 1)与(m, n)处权值为0

Analyze

两个二维DP同时进行 -> 四维DP

单独处理走到同一格的情况

Code

#include <cmath>
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;

int mp[51][51];
int dp[51][51][51][51];

int main()
{
    int n, m;
    cin >> n >> m;
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= m; ++j)
            scanf("%d",&mp[i][j]);

    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= m; ++j)
            for (int k = 1; k <= n; ++k)
                for (int l = 1; l <= m; ++l)
                {
                    int a = max(dp[i - 1][j][k - 1][l], dp[i - 1][j][k][l - 1]);
                    int b = max(dp[i][j - 1][k - 1][l], dp[i][j - 1][k][l - 1]);
                    dp[i][j][k][l] = mp[i][j] + mp[k][l] + max(a, b);
                    if(i == k && j == l)
                        dp[i][j][k][l] -= mp[i][j];
                }

    cout << max(dp[n - 1][m][n][m - 1], dp[n][m - 1][n - 1][m]) + mp[n][m] << '\n';
    return 0;
}
Site by Baole Zhao | Powered by Hexo | theme PreciousJoy