最大子矩阵
题目描述
这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩阵分值之和最大。注意:选出的k个子矩阵不能相互重叠。
输入格式
第一行为n,m,k(1≤n≤100,1≤m≤2,1≤k≤10),接下来n行描述矩阵每行中的每个元素的分值(每个元素的分值的绝对值不超过32767)。
输出格式
只有一行为k个子矩阵分值之和最大为多少。
输入输出样例
输入
3 2 2 1 -3 2 3 -2 3
输出
9题目思路注意到m只会为1或2,为1时就是简单的一维线性dp过去,为2时就多加几个决策,有点麻烦dp1[i][j]表示在所取矩形最大坐标为i且取k个矩形的最大值,dp2[i][j][t]表示在所取矩形第一位最大坐标为i第二维最大坐标为j且取k个矩形的最大值
#include<bits/stdc++.h>
#define mod 9999973
#define ll long long
using namespace std;
int n,m,k,dp2[101][101][11],g[101][3],dp1[101][11],sum1[101],sum2[101];
int main()
{
memset(dp1,128,sizeof(dp1));
memset(dp2,128,sizeof(dp2));
cin>>n>>m>>k;
for(int i = 1;i<=n;i++)
for(int j = 1;j<=m;j++)
cin>>g[i][j];
if(m==1)
{
for(int i = 1;i<=n;i++)
sum1[i] = sum1[i-1]+g[i][1];
dp1[0][0] = 0;
for(int i = 1;i<=n;i++)
{
dp1[i][0] = 0;
for(int j = 0;j<i;j++)
for(int t = 1;t<=k;t++)
dp1[i][t] = max(max(dp1[i-1][t],dp1[i][t]),dp1[j][t-1]+sum1[i]-sum1[j]);
}
cout<<dp1[n][k];
}
else
{
for(int i = 1;i<=n;i++)
sum1[i] = sum1[i-1]+g[i][1];
for(int i = 1;i<=n;i++)
sum2[i] = sum2[i-1]+g[i][2];
dp2[0][0][0] = 0;
for(int i = 1;i<=n;i++)
{
dp2[i][i][0] = 0;
for(int j = 0;j<=i;j++)
{
for(int t = 0;t<=i;t++)
{
for(int h = 1;h<=k;h++)
{
int p = max(j,t);
if(t)
dp2[i][t][h] = max(max(dp2[i][t][h],max(dp2[i-1][t-1][h],max(dp2[i-1][t][h],dp2[i][t-1][h]))),dp2[j][t][h-1]+sum1[i]-sum1[j]);
else
dp2[i][t][h] = max(max(dp2[i][t][h],max(dp2[i-1][t][h],max(dp2[i-1][t][h],dp2[i][t][h]))),dp2[j][t][h-1]+sum1[i]-sum1[j]);
if(j)
dp2[j][i][h] = max(max(dp2[j][i][h],max(dp2[j-1][i-1][h],max(dp2[j-1][i][h],dp2[j][i-1][h]))),dp2[j][t][h-1]+sum2[i]-sum2[t]);
else
dp2[j][i][h] = max(max(dp2[j][i][h],max(dp2[j][i-1][h],max(dp2[j][i][h],dp2[j][i-1][h]))),dp2[j][t][h-1]+sum2[i]-sum2[t]);
dp2[i][i][h] = max(max(dp2[i][i][h],max(dp2[i-1][i-1][h],max(dp2[i-1][i][h],dp2[i][i-1][h]))),dp2[j][t][h-1]+sum1[i]-sum1[p]+sum2[i]-sum2[p]);
}
}
}
}
int ans = 0;
for(int i = 0;i<=n;i++)
for(int j = 0;j<=n;j++)
ans = max(ans,dp2[i][j][k]);
cout<<ans;
}
return 0;
}