一.题意
n * m 的矩阵分成 k 组互不重叠的矩阵,求最大的子矩阵和。
二.题解
特别注意到的是 m 的值为 1 或者 2,所以可以由比较简单的方法写出。
考虑 代表第一列前 i 个元素和第二列前 j 个元素组成 k 个矩阵的最大值。
有以下的递推方程:
- 由前一状态推出,
- 枚举第一列,
- 枚举第二列,
- 当第一列和第二列取同样多的元素可以考虑合并,
三.代码:
#include<bits/stdc++.h>
#define mp make_pair
#define pb push_back
#define ld long double
#define ll long long
#define ull unsigned long long
#define fi first
#define se second
#define inf 0x3f3f3f3f
#define io std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
const int manx=1e6+5;
const int N=1e3+5;
const int mod=1e9+7;
ll s[N][3],dp[N][N][15];
ll n,m,ans,k,x;
int main(){
io; cin>>n>>m>>k; ll K=k;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>x,s[i][j]=s[i-1][j]+x;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
for(int k=1;k<=K;k++){
dp[i][j][k]=max(dp[i-1][j][k],dp[i][j-1][k]);
for(int l=0;l<i;l++)
dp[i][j][k]=max(dp[i][j][k],dp[l][j][k-1]+s[i][1]-s[l][1]);
for(int l=0;l<j;l++)
dp[i][j][k]=max(dp[i][j][k],dp[i][l][k-1]+s[j][2]-s[l][2]);
if(i==j)
for(int l=0;l<i;l++)
dp[i][j][k]=max(dp[i][j][k],dp[l][l][k-1]+s[i][1]+s[j][2]-s[l][1]-s[l][2]);
}
cout<<dp[n][n][K];
return 0;
} 
京公网安备 11010502036488号