[模板] 四维dp

luogu P1004 方格取数
另例:P1006 传纸条

#include <bits/stdc++.h>
using namespace std;
int dp[11][11][11][11], a[11][11], n, x, y, z;
int main()
{
    cin >> n;
    while (cin >> x >> y >> z && x && y && z)
        a[x][y] = z;
    for (int i = 1; i <= n; i++){
        for (int j = 1; j <= n; j++){
            for (int k = 1; k <= n; k++){
                for (int l = 1; l <= n; l++){
                    dp[i][j][k][l] = max(max(max(dp[i-1][j][k-1][l], dp[i-1][j][k][l-1]), dp[i][j-1][k-1][l]), dp[i][j-1][k][l-1]) + a[i][j] + a[k][l];
                    if (i == k && j == l) dp[i][j][k][l] -= a[i][j];
                }
            }
        }
    }
    cout << dp[n][n][n][n];
}
    for(l=2;l<=n*2;l++)//每个点最少横着竖着都走一格,最多都走n格就到终点
        for(i=l-1;i>=1;i--)//和前面说的一样,倒着做
            for(ii=l-1;ii>=1;ii--)
            {
                j=l-i;jj=l-ii;//i+j=ii+jj=l
                f[i][ii]=max(max(f[i][ii],f[i-1][ii-1]),max(f[i-1][ii],f[i][ii-1]))+map[i][j];
//重点说明一下吧,这里省略了很多。这里由于步数确定,利用i和ii就可以确定j和jj,从而使得原来的四维,在空间上压成两维。
//具体地说,如果i不减1,那么j就要减1,才能保证步数和为l-1。如果ii-1,jj不就减1。
                f[i][ii]+=map[ii][jj]*(i!=ii);
//如果i==ii,其实就是(i==ii&&j==jj),因为和都是l嘛。如果走过一遍,第二遍走得到的值就是0(题目上说的)。
            }

猜你喜欢

转载自blog.csdn.net/weixin_45502929/article/details/106771118