题目
一定会保证走出的路线是好几个底在一个水平线高低可能不同的矩形紧挨着。
然后总共有2*k+1个矩阵 第奇数个矩阵比旁边的矩阵高。
剩下的就是二维DP
f[i][j][k][h]:以第i行第j列为右下角而且这是选的第k个矩阵 高度为h 的权值和最大是多少?
1.第i行(定量):第j列与第j-1列是同一个矩形 f[i][j][k][h]=f[i][j-1][k][h]+s[j][i]-s[j][h-1];
2.第i行(定量):
1*.k为奇数:(应该由第k-1个矩形走向k是往高处走的)
f[i][j][k][h]=f[i][j-1][k-1][h*]+s[j][i]-s[j][h-1];(h*<h)
2*.k为偶数:(应该由第k-1个矩形走向k是往低处走的)
f[i][j][k][h]=f[i][j-1][k-1][h*]+s[j][i]-s[j][h-1];(h*>h)
由于第2种情况每次枚举最大的f[i][j-1][k][h*]很慢.所以我们依靠另一个数组g[i][j][k][h][0/1];
g[i][j][k][h][0/1]:以第i行第j列为右下角而且这是选的第k个矩阵 高度小于h/大于h 的f[i][j][k][h]的最大和.
#include<bits/stdc++.h>
using namespace std;
const int N=100+5,INF=0x3f3f3f3f;
int f[N][23][N],g[N][23][N][2],s[N][N],a[N][N];
//f[i][j][k][h]:以第i行第j列为右下角而且这是选的第k个矩阵 高度为h 的权值和最大是多少?
//1.第i行(定量):第j列与第j-1列是同一个矩形 f[i][j][k][h]=f[i][j-1][k][h]+s[j][i]-s[j][h-1];
//2.第i行(定量):{
// 1*.k为奇数:(应该由第k-1个矩形走向k是往高处走的) f[i][j][k][h]=f[i][j-1][k-1][h*]+s[j][i]-s[j][h-1];(h*<h)
// 2*.k为偶数:(应该由第k-1个矩形走向k是往低处走的) f[i][j][k][h]=f[i][j-1][k-1][h*]+s[j][i]-s[j][h-1];(h*>h)
//}
//由于第2种情况每次枚举最大的f[i][j-1][k][h*]很慢.所以我们依靠另一个数组g[i][j][k][h][0/1];
//g[i][j][k][h][0/1]:以第i行第j列为右下角而且这是选的第k个矩阵 高度小于h/大于h 的f[i][j][k][h]的最大和.
int n,m,K;
int DP(){
K=(K<<1|1);
for(int k=1;k<=K;++k)//emmm 初始化!
for(int h=1;h<=n;++h) f[0][k][h]=g[0][k][h][0]=g[0][k][h][1]=-INF;
int ans=-INF;
for(int i=1;i<=n;++i){
for(int j=1;j<=m;++j){
for(int k=1;k<=K;++k){
for(int h=1;h<=i;++h) f[j][k][h]=max(f[j-1][k][h],g[j-1][k-1][h][k&1])+s[i][j]-s[h-1][j];
g[j][k][1][0]=-INF;
for(int h=2;h<=i;++h) g[j][k][h][0]=max(g[j][k][h-1][0],f[j][k][h-1]);
g[j][k][i][1]=-INF;
for(int h=i-1;h>=1;--h) g[j][k][h][1]=max(g[j][k][h+1][1],f[j][k][h+1]);
}
ans=max(ans,max(f[j][K][i],g[j][K][i][0]));
}
}
return ans;
}
int main(){
scanf("%d%d%d",&n,&m,&K);
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j) scanf("%d",&a[i][j]),s[i][j]=s[i-1][j]+a[i][j];
printf("%d\n",DP());
}
来源:https://blog.csdn.net/qq_42576687/article/details/100545678