P1004 方格取数

P1004 方格取数

 

解题思路:

这个题目显然可以搜索,运用dfs的知识去求解

但我们毕竟是dp题,还是考虑动态规划的方法

我们发现这道题目中说:一个人走两次 如果按照如上思路,那么会用两次的计算,相对来说比较复杂

对于两者相加求和的最大值来说并不好做 考虑换一种思路

我们可以看做是两个人同时走,求最大值 这样只需要进行一次dp求最大值了

需要4维dp 但是一看到n最大为9,我们也就可以放心做了

我们记f[i][j][k][l]表示第1条路线的i,j走法和第2条路线的k,l走法

不难发现第1条路线只可能是从i-1,j或者i,j-1转移,第2条路线也只可能从k-1,l或者k,l-1转移

因为是2个人走,如果走到一点我们的那个点就要打标记说那点上面的值为0

所以当i=k且j=l的时候,需要进行一步减的操作,减去多算的那一部分得分

因此我们得到了我们的动归方程 f[i][j][k][l]=max(max(f[i-1][j][k-1][l],f[i-1][j][k][l-1]),max(f[i][j-1][k-1][l],f[i][j-1][k][l-1]))+a[i][j]+a[k][l]

代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int f[12][12][12][12],a[12][12],n,x,y,z;
int main()
{
    cin>>n>>x>>y>>z;
    while(x!=0||y!=0||z!=0)
    {
        a[x][y]=z;
        cin>>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(max(f[i-1][j][k-1][l],f[i-1][j][k][l-1]),max(f[i][j-1][k-1][l],f[i][j-1][k][l-1]))+a[i][j]+a[k][l];
                    if(i==k&&l==j)
                        f[i][j][k][l]-=a[i][j];
                }
            }
        }
    }
    cout<<f[n][n][n][n];
    return 0;
}
原文地址:https://www.cnblogs.com/gongcheng456/p/12860483.html