P1004 方格取数(多维dp)

题目链接:https://www.luogu.com.cn/problem/P1004

原来还可以这么dp...

题意:

给出一个方阵的行列长和部分方格中的数,问从左上角走到右下角所能取得的数之和的最大值(走两遍,每个方格中的数取后为0)。

思路:

$dp[i][j][k][l]$,$(i,j)$为第一遍走的坐标,$(k,l)$为第二遍走的坐标。

$dp[i][j][k][l]=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]$。

若两点重合,因为一个数只能加一次,所以需减去一个值。

#include <bits/stdc++.h>
using namespace std;
const int M=10;
int a[M][M];
int dp[M][M][M][M];
int main()
{
    int n,x,y,v;cin>>n>>x>>y>>v;
    while(x||y||v){
        a[x][y]=v;
        cin>>x>>y>>v;
    }
    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(dp[i-1][j][k-1][l],dp[i-1][j][k][l-1]),
                        max(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];
    return 0;
}

 

  

 

posted @ 2020-04-03 19:26  Kanoon  阅读(156)  评论(0)    收藏  举报