题解:P12679 Brooklyn Round 1 & NNOI Round 1 C - Field
鲜花
期末考完,作业全免,心情很好,故作此文。
题解
看到这种求矩阵路径最大的题,先考虑 dp。
但是对于这道题只设置一个状态显然是不够的,因为你无法使用一个状态来处理黑色格子“延迟加”这种东西,因此考虑设两个状态:
这样,转移就很简单了,遇到白格子的时候,分讨一下上一个格子的颜色;遇到黑格子的时候,记得比较的是 dp2 的大小。
不懂的参见代码:
#include<bits/stdc++.h>
using namespace std;
int a[1010][1010];
bool b[1010][1010];
int dp1[1010][1010];
int dp2[1010][1010];
int main(){
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)cin>>a[i][j];
for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)cin>>b[i][j];
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(b[i][j]){
if(b[i][j-1]){
dp1[i][j]=dp1[i][j-1]+a[i][j];
dp2[i][j]=dp2[i][j-1]+a[i][j];
}
else{
dp1[i][j]=dp1[i][j-1];
dp2[i][j]=dp2[i][j-1];
}
if(b[i-1][j]){
dp1[i][j]=max(dp1[i][j],dp1[i-1][j]+a[i][j]);
dp2[i][j]=max(dp2[i][j],dp2[i-1][j]+a[i][j]);
}
else{
dp1[i][j]=max(dp1[i][j],dp1[i-1][j]);
dp2[i][j]=max(dp2[i][j],dp2[i-1][j]);
}
}
else{
if(dp2[i][j-1]>dp2[i-1][j]){
dp1[i][j]=dp2[i][j-1];
dp2[i][j]=dp1[i][j]+a[i][j];
}
else{
dp1[i][j]=dp2[i-1][j];
dp2[i][j]=dp1[i][j]+a[i][j];
}
}
}
}
cout<<dp1[n][m];
return 0;
}