SCOI2005 最大子矩阵
m=1的时候很简单 不说了。
m=2的时候的动态规划需要讨论,有点麻烦。
我们设dp[i][j][k]为处理到第i行,已经使用了j个矩阵,这一行采取k的取用方式。
其中0表示什么都不拿。
1表示只要左边的。
2表示只要右边的。
3表示两边都要,且分开加入矩阵。
4表示两边都要,放在一个矩阵中。
然后转移方程可以参见代码。
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int dp[105][15][5];
int mp[105][2];
int main(){
int n,m,k;cin >> n >> m >> k;
for(int i = 1;i <= n;i ++)for(int j = 0;j < m;j ++)cin >> mp[i][j];
for(int i = 1;i <= n;i ++){
int add0 = 0;
int add1 = mp[i][0];
int add2 = mp[i][1];
int add3 = mp[i][0] + mp[i][1];
for(int j = 1;j <= k;j ++){
for(int u = 0;u <= 4;u ++)
dp[i][j][0] = max( dp[i][j][0],dp[i-1][j][u] + add0 );
dp[i][j][1] = max( dp[i][j][1],dp[i-1][j][1] + add1 );
dp[i][j][1] = max( dp[i][j][1],dp[i-1][j-1][1] + add1 );
dp[i][j][1] = max( dp[i][j][1],dp[i-1][j][3] + add1 );
dp[i][j][1] = max( dp[i][j][1],dp[i-1][j-1][0] + add1 );
dp[i][j][1] = max( dp[i][j][1],dp[i-1][j-1][2] + add1 );
dp[i][j][1] = max( dp[i][j][1],dp[i-1][j-1][4] + add1 );
dp[i][j][2] = max( dp[i][j][2],dp[i-1][j][2] + add2 );
dp[i][j][2] = max( dp[i][j][2],dp[i-1][j-1][2] + add2 );
dp[i][j][2] = max( dp[i][j][2],dp[i-1][j][3] + add2 );
dp[i][j][2] = max( dp[i][j][2],dp[i-1][j-1][0] + add2 );
dp[i][j][2] = max( dp[i][j][2],dp[i-1][j-1][1] + add2 );
dp[i][j][2] = max( dp[i][j][2],dp[i-1][j-1][4] + add2 );
dp[i][j][4] = max( dp[i][j][4],dp[i-1][j][4] + add3 );
dp[i][j][4] = max( dp[i][j][4],dp[i-1][j-1][4] + add3 );
dp[i][j][4] = max( dp[i][j][4],dp[i-1][j-1][0] + add3 );
dp[i][j][4] = max( dp[i][j][4],dp[i-1][j-1][1] + add3 );
dp[i][j][4] = max( dp[i][j][4],dp[i-1][j-1][2] + add3 );
dp[i][j][4] = max( dp[i][j][4],dp[i-1][j-1][3] + add3 );
if( j == 1 )continue;
dp[i][j][3] = max( dp[i][j][3],dp[i-1][j][3] + add3 );
dp[i][j][3] = max( dp[i][j][3],dp[i-1][j-1][3] + add3 );
dp[i][j][3] = max( dp[i][j][3],dp[i-1][j-2][0] + add3 );
dp[i][j][3] = max( dp[i][j][3],dp[i-1][j-2][4] + add3 );
dp[i][j][3] = max( dp[i][j][3],dp[i-1][j-1][1] + add3 );
dp[i][j][3] = max( dp[i][j][3],dp[i-1][j-1][2] + add3 );
}
}
int ans = 0;
for(int i = 0;i <= k;i ++)for(int j = 0;j <= 4;j ++)ans = max( ans,dp[n][i][j] );
cout << ans;
return 0;
}