• [BZOJ1084][SCOI2005]最大子矩阵


    1084: [SCOI2005]最大子矩阵

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 2984  Solved: 1490
    [Submit][Status][Discuss]

    Description

      这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩阵分值之和最大。注意:选出的k个子矩阵
    不能相互重叠。

    Input

      第一行为n,m,k(1≤n≤100,1≤m≤2,1≤k≤10),接下来n行描述矩阵每行中的每个元素的分值(每个元素的
    分值的绝对值不超过32767)。

    Output

      只有一行为k个子矩阵分值之和最大为多少。

    Sample Input

    3 2 2
    1 -3
    2 3
    -2 3

    Sample Output

    9
     
    发现最多只有两列,肯定要从这里入手
    设$f[i][j][k]$表示第$1$列选了前$i$行,第$2$列选了前$j$行,一共选了$k$次的最大值
    转移时考虑选或者不选,要选的话选几列
    复杂度$O(n^3k)$
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    char buf[10000000], *ptr = buf - 1;
    inline int readint(){
        int f = 1, n = 0;
        char ch = *++ptr;
        while (ch < '0' || ch > '9'){
            if(ch == '-') f = -1;
            ch = *++ptr;
        }
        while (ch <= '9' && ch >= '0'){
            n = (n << 1) + (n << 3) + ch - '0';
            ch = *++ptr;
        }
        return f * n;
    }
    const int maxn = 100 + 10, INF = 0x7f7f7f7f;
    int N, M, K;
    int s[maxn], sum[maxn][3];
    int f[maxn][11], g[maxn][maxn][11];
    void work1(){
        s[0] = 0;
        for(int i = 1; i <= N; i++) s[i] = s[i - 1] + readint();
        for(int i = 0; i <= N; i++)
            for(int k = 1; k <= K; k++)
                f[i][k] = -INF;
        for(int i = 1; i <= N; i++)
            for(int k = 1; k <= K; k++){
                f[i][k] = f[i - 1][k];
                for(int j = 0; j < i; j++)
                    f[i][k] = max(f[i][k], f[j][k - 1] + s[i] - s[j]);
            }
        printf("%d
    ", f[N][K]);
    }
    void work2(){
        sum[0][1] = sum[0][2] = 0;
        for(int i = 1; i <= N; i++){
            sum[i][1] = sum[i - 1][1] + readint();
            sum[i][2] = sum[i - 1][2] + readint();
        }
        for(int i = 0; i <= N; i++)
            for(int j = 0; j <= N; j++)
                for(int k = 1; k <= K; k++)
                    g[i][j][k] = -INF;    
        for(int i = 1; i <= N; i++)
            for(int j = 1; j <= N; j++)
                for(int k = 1; k <= K; k++){
                    g[i][j][k] = max(g[i - 1][j][k], g[i][j - 1][k]);
                    for(int L = 0; L < i; L++)
                        g[i][j][k] = max(g[i][j][k], g[L][j][k - 1] + sum[i][1] - sum[L][1]);
                    for(int L = 0; L < j; L++)
                        g[i][j][k] = max(g[i][j][k], g[i][L][k - 1] + sum[j][2] - sum[L][2]);
                    if(i == j)
                        for(int L = 0; L < i; L++)
                            g[i][j][k] = max(g[i][j][k], g[L][L][k - 1] + sum[i][1] + sum[i][2] - sum[L][1] - sum[L][2]);
                }
        printf("%d
    ", g[N][N][K]);
    }
    int main(){
        fread(buf, sizeof(char), sizeof(buf), stdin);
        N = readint();
        M = readint();
        K = readint();
        if(M == 1) work1();
        else work2();
        return 0;
    }
  • 相关阅读:
    mysql无法启动ERROR! MySQL is running but PID file could not be found ?
    mybatis返回list很智能很简答的,只需要配置resultmap进行类型转换,你dao方法直接写返回值list<对应的object>就行了啊
    mybatis resultmap标签type属性什么意思
    python学习笔记——第三章 串
    POJ 2485:Highways(最小生成树&amp;&amp;prim)
    G-Sensor 校准标准
    Unity3D 4.x 使用Mecanim实现动画控制
    quartz群调查调度机制和源代码分析
    什么是你的七个核心竞争力-弱点让你闪
    poj 3368 Frequent values(段树)
  • 原文地址:https://www.cnblogs.com/ruoruoruo/p/7598606.html
Copyright © 2020-2023  润新知