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; }