Luogu P1004 [Noip2000]方格取数___动态规划

题目大意:

给出N*N的方格图,以及给出在上面的数,问一个人从[1,1]走到[N,N]的路径加上从[N,N]回到[1,1]的路径总和最大值,同一点上的数只能被计算一次。

N≤9

分析:

其实就是一个人在[1,1]走2条到[N,N]的不同路,使总和最大
设f[i][j][k][l]表示第一条路走到[i,j]第二条路走到[k,l]的路径总和最大值.
则可以推出:
f[i][j][k][l] = max{f[i-1][j][k-1][l],f[i-1][j][k][l-1],f[i][j-1][k-1][l],f[i][j-1][k][l-1]}+a[i][j]+a[k][l]
注意当点相同时要减去多算的一次

代码:

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#define N 15

using namespace std;

int n,m,a[N][N],f[N][N][N][N];

int main(){
    scanf("%d",&n);
    int x,y,z;
    scanf("%d%d%d",&x,&y,&z);
    while (x || y || z){
           a[x][y] = z;
           scanf("%d%d%d",&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++){
                        f[i][j][k][l] = max(f[i-1][j][k-1][l] , f[i][j-1][k-1][l]);
                        f[i][j][k][l] = max(f[i][j][k][l] , max(f[i-1][j][k][l-1] , f[i][j-1][k][l-1]));
                        f[i][j][k][l] += a[i][j] + a[k][l];
                        if (i == k && j == l) f[i][j][k][l] -= a[i][j]; 
                   }
    printf("%d\n",f[n][n][n][n]);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/gx_man_vip/article/details/80185722