题意:略
题记:由于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; }