这道题还是一道很不错的DP题,我们考虑当m=1时,是不是相当与一个序列操作,我们可以设计一个状态f[i][j],表示考虑到第i行,选了j个矩形的最大值,那么我们考虑转移,当前行只有2种转移的方式,一种是什么也不做,即不选这个格子,还有一种是让这个格子和上面的格子形成一个矩形。那么对于m=2的情况,我们可以再加1维,f[i][j][k]表示第1列考虑到i,第2列考虑到j,选了k个矩形的最大值,那么这样的话就有多了一种转移,当i==j时,我们可以让第i行和上面的行形成一个大矩形,其他的转移类比m=1时的情况。另外,一开始我把m=1和m=2写了两个函数处理,结果一直WA,改成在主函数里就好了,我也不知道怎么回事,有哪位神犇知道吗
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define maxn 105
int n,m,z;
int main()
{
scanf("%d%d%d",&n,&m,&z);
if (m==1)
{
int f[maxn][11],sum[maxn];
memset(sum,0,sizeof sum);
for (int i=0;i<=n;i++)
for (int k=1;k<=z;k++) f[i][k]=-1e9;
for (int i=1;i<=n;i++)
{
int a;
scanf("%d",&a);
sum[i]=sum[i-1]+a;
}
for (int i=1;i<=n;i++)
for (int k=1;k<=z;k++)
{
f[i][k]=f[i-1][k];
for (int j=0;j<i;j++)
f[i][k]=max(f[j][k-1]+sum[i]-sum[j],f[i][k]);
}
printf("%d\n",f[n][z]);
}
else
{
int f[maxn][maxn][11],sum[maxn][4];
memset(sum,0,sizeof sum);
for (int i=0;i<=n;i++)
for (int j=0;j<=n;j++)
for (int k=1;k<=z;k++) f[i][j][k]=-1e9;
for (int i=1;i<=n;i++)
{
int a,b;
scanf("%d%d",&a,&b);
sum[i][1]=sum[i-1][1]+a;
sum[i][2]=sum[i-1][2]+b;
sum[i][3]=sum[i-1][3]+a+b;
}
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
for (int k=1;k<=z;k++)
{
f[i][j][k]=max(f[i-1][j][k],f[i][j-1][k]);
for (int ii=0;ii<i;ii++)
f[i][j][k]=max(f[i][j][k],f[ii][j][k-1]+sum[i][1]-sum[ii][1]);
for (int jj=0;jj<j;jj++)
f[i][j][k]=max(f[i][j][k],f[i][jj][k-1]+sum[j][2]-sum[jj][2]);
if (i==j)
for (int ij=0;ij<i;ij++)
f[i][j][k]=max(f[i][j][k],f[ij][ij][k-1]+sum[i][3]-sum[ij][3]);
}
printf("%d\n",f[n][n][z]);
}
return 0;
}