fijk表示第一列选了i个第二列选了j个已经搞定了k个子矩阵的情况
然后考虑转移,可以不选,从上面转移作为初值,可以选,于是枚举之前的进行转移就行
实际上我们看到了m<=2并想到了分类转移的思想的时候已经变得很简单了
听说丽洁姐姐的博客里面有详细,但是并不能打开【大概是RP不好
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#define LL long long
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define down(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
inline LL read()
{
LL d=0,f=1;char s=getchar();
while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();}
return d*f;
}
#define N 105
#define M 15
#define NM 5
int a[N][M],s[N][M];
int f[N][N][M];
int n,m,nm,ans=0;
void init()
{
memset(s,0,sizeof(s));
n=read(),m=read(),nm=read();
fo(i,1,n)
{
fo(j,1,m)
{
int x=read();
a[i][j]=x;
s[i][j]=s[i-1][j]+a[i][j];
}
}
}
void ini()
{
memset(s,0,sizeof(s));
scanf("%d%d%d",&n,&m,&nm);
fo(i,1,n)
{
fo(j,1,m)
{
int x;
scanf("%d",&x);
a[i][j]=x;
s[i][j]=s[i-1][j]+a[i][j];
}
}
}
void DP()
{
memset(f,0,sizeof(f));
fo(p,1,nm)
fo(i,1,n)
fo(j,1,n)
{
f[i][j][p]=max(f[i-1][j][p],f[i][j-1][p]);
fo(q,0,max(i,j)-1)
{
if(i==j)
{
f[i][j][p]=max(f[i][j][p],f[q][q][p-1]+s[i][1]-s[q][1]+s[j][2]-s[q][2]);
}
if(q<j)f[i][j][p]=max(f[i][j][p],f[i][q][p-1]+s[j][2]-s[q][2]);
if(q<i)f[i][j][p]=max(f[i][j][p],f[q][j][p-1]+s[i][1]-s[q][1]);
}
}
}
void OUT()
{
cout<<f[n][n][nm]<<endl;
}
int main()
{
ini();
DP();
OUT();
return 0;
}