BZOJ1084 SCOI2005最大子矩阵

时间:2023-03-10 04:27:18
BZOJ1084 SCOI2005最大子矩阵

考虑DP

f[i][j][k]表示一行到i一行到j共取k块最大值,类似于最长公共子序列n^2那种

注意相等时可以一起拿

By:大奕哥

 #include<bits/stdc++.h>
using namespace std;
int n,m,K,g[][][],f[][],s[][],x;
int main()
{
scanf("%d%d%d",&n,&m,&K);
for(int i=;i<=n;++i)
for(int j=;j<=m;++j)
{
scanf("%d",&x);
s[i][j]=s[i-][j]+x;
}
if(m==)
{
memset(f,-0x3f,sizeof(f));
for(int i=;i<=n;++i)f[i][]=;
for(int i=;i<=n;++i)
{
for(int k=;k<=K;++k)
{
f[i][k]=max(f[i][k],f[i-][k]);
for(int j=;j<i;++j)
f[i][k]=max(f[i][k],f[j][k-]+s[i][]-s[j][]);
}
}
printf("%d\n",f[n][K]);
}
else
{
memset(g,-0x3f,sizeof(g));
for(int i=;i<=n;++i)
for(int j=;j<=n;++j)
g[i][j][]=;
for(int i=;i<=n;++i)
for(int j=;j<=n;++j)
{
for(int k=;k<=K;++k)
{
g[i][j][k]=max(g[i-][j][k],g[i][j-][k]);
for(int p=;p<i;++p)g[i][j][k]=max(g[i][j][k],g[p][j][k-]+s[i][]-s[p][]);
for(int p=;p<j;++p)g[i][j][k]=max(g[i][j][k],g[i][p][k-]+s[j][]-s[p][]);
if(i==j)
for(int p=;p<i;++p)
g[i][j][k]=max(g[i][j][k],g[p][p][k-]+s[i][]+s[i][]-s[p][]-s[p][]);
}
}
printf("%d\n",g[n][n][K]);
}
return ;
}