zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    软件工程第八周总结
    一维最大子数组的和续
    程序员修炼之道阅读笔记02
    软件工程第七周总结
    团队软件的NABCD—校园知网
    程序员修炼之道阅读笔记01
    软件项目管理阅读笔记01
    个人作业4 结对开发地铁
    学习进度五
    学习进度四
  • 原文地址:https://www.cnblogs.com/fengxunling/p/10269755.html
Copyright © 2011-2022 走看看