最大子矩阵
题目描述
这里有一个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; }