这个可以发现形状肯定是 下面平 上面一高一低的 总共2k+1
那么乱DP一下就好了
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#define cl(x) memset(x,0,sizeof(x))
using namespace std;
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }
return *p1++;
}
inline void read(int &x){
char c=nc(),b=1;
for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;
for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;
}
const int N=105;
int in,im,ia[N][N],K;
int n,m,Ans=-1<<30;
int a[N][N];
struct array{
int a[N],max1[N],max2[N];
array() { }
array(int m){
cl(a); cl(max1); cl(max2);
for (int i=1;i<=m;i++) a[i]=max1[i]=max2[i]=-1<<30;
}
int &operator [](int x){
return a[x];
}
int maxv(int l,int r){
if (l>r) return -1<<30;
if (l==1) return max1[r];
if (r==m) return max2[l];
}
void maintain(){
max1[1]=a[1]; for (int i=2;i<=m;i++) max1[i]=max(max1[i-1],a[i]);
max2[m]=a[m]; for (int i=m-1;i;i--) max2[i]=max(max2[i+1],a[i]);
}
};
array f[N][25];
inline void Solve(){
for (int i=0;i<=n;i++) for (int k=1;k<=K;k++) f[i][k]=array(m);
for (int i=1;i<=n;i++)
for (int k=1;k<=i;k++){
for (int j=1;j<=m;j++){
f[i][k][j]=f[i-1][k][j]+a[i][j];
if (k==1){
f[i][k][j]=max(f[i][k][j],a[i][j]);
}else{
if (k&1)
f[i][k][j]=max(f[i][k][j],f[i-1][k-1].maxv(1,j-1)+a[i][j]);
else
f[i][k][j]=max(f[i][k][j],f[i-1][k-1].maxv(j+1,m)+a[i][j]);
}
}
f[i][k].maintain();
}
int tem=-1<<30;
for (int i=1;i<=n;i++)
tem=max(tem,f[i][K].maxv(1,m));
Ans=max(Ans,tem);
}
int main(){
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
read(in); read(im); read(K); K=K<<1|1;
for (int i=1;i<=in;i++) for (int j=1;j<=im;j++) read(ia[i][j]);
for (int i=1;i<=in;i++){
n=im; m=i;
for (int j=1;j<=n;j++)
for (int k=1;k<=m;k++)
a[j][k]=a[j][k-1]+ia[m-k+1][j];
Solve();
}
printf("%d\n",Ans);
return 0;
}