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;
}
posted @ 2019-01-15 00:01  风浔凌  阅读(137)  评论(0编辑  收藏  举报