题意:略
题记:由于m的范围在1 ≤ m ≤ 2。所以很容易就想到dp。
dp[i][j][k]表示的是在第一列的前i个数,第二列的前j个数选k个矩阵的最大值。
那么dp过程中大致有两种情况:
1、不需要重新选一个新矩阵
dp[i][j][k]=max(dp[i][j-1][k],dp[i-1][j][k]);
2、需要重新选一个新矩阵:
首先矩阵也分为两种(l为矩阵长度)
(1)1乘l的矩阵
dp[i][j][k]=max(dp[i][l][k-1]+sum[j][2]-sum[l][2],dp[i][j][k]);
dp[i][j][k]=max(dp[l][j][k-1]+sum[i][1]-sum[l][1],dp[i][j][k]);
(2)2乘l的矩阵(只有i==j时候才有2乘l的矩阵)
dp[i][j][k]=max(dp[l][l][k-1]+sum[i][1]-sum[l][1]+sum[j][2]-sum[l][2],dp[i][j][k]);
枚举所有l的长度,全部取一个最大值,最后dp[n][n][p]就是答案。
#include<bits/stdc++.h>
using namespace std;
const int N=110;
int a[N][3],sum[N][3];
int dp[N][N][N];
int main(){
int n,m,p;
cin>>n>>m>>p;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>a[i][j];
sum[i][j]=sum[i-1][j]+a[i][j];
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
for(int k=1;k<=p;k++){
dp[i][j][k]=max(dp[i][j-1][k],dp[i-1][j][k]);
//不需要重新选一个新矩阵的情况
for(int l=0;l<j;l++)
dp[i][j][k]=max(dp[i][l][k-1]+sum[j][2]-sum[l][2],dp[i][j][k]);
//枚举右边选一个新矩阵的长度
for(int l=0;l<i;l++)
dp[i][j][k]=max(dp[l][j][k-1]+sum[i][1]-sum[l][1],dp[i][j][k]);
//枚举左边选一个新矩阵的长度
if(i==j){
//当i==j时可以选一个2*l的新矩阵
for(int l=0;l<i;l++)
dp[i][j][k]=max(dp[l][l][k-1]+sum[i][1]-sum[l][1]+sum[j][2]-sum[l][2],dp[i][j][k]);
}
}
}
}
cout<<dp[n][n][p]<<endl;
return 0;
}

京公网安备 11010502036488号