zoukankan      html  css  js  c++  java
  • [SCOI2005]最大子矩阵

    题目描述

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

    输入输出格式

    输入格式:

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

    输出格式:

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

    输入输出样例

    输入样例#1:
    3 2 2
    1 -3
    2 3
    -2 3
    
    输出样例#1:
    9

    解析:

    刚开始看并没有思路,直到看到了数据范围  m <= 2好吧

    最多也就是两行的矩阵  

    这样的话我们可以暴力手模一下情况,就可以看出转移有那种情况

    dp[i][j][k] 表示第一行选取到了第i个,第二行选取了第j个,选取了k个矩形的最大取值

    之后分析一下

    dp[i ][j][k]可以由哪些情况转移来呢

    1.啥都不拿-.-  继承父辈的衣钵 在 dp[i - 1 ][j][k] 和dp[i][j - 1][k] 中去较大值

    2.拿第一列的,枚举一下从哪里开始拿,

    3.拿第二列的,枚举一下从哪里开始拿

    4.拿两列的,枚举一下从哪里开始拿

    然后涉及大量求和

    前缀和优化

    代码:

    #include<cstdio>
    #include<iostream> 
    #include<algorithm>
    using namespace std;
    
    int note[101][3];
    int sum1[101];
    int sum2[101];
    int sum12[101]; 
    
    int dp[101][101][15];
    
    int main()
    {
        int n,m,k;
        scanf("%d%d%d",&n,&m,&k);
        for(int i = 1;i <= n;i++)
        {
            for(int j = 1;j <= m;j++)
            {
                scanf("%d",&note[i][j]);
            }
            sum1[i] = sum1[i - 1] + note[i][1];
            sum2[i] = sum2[i - 1] + note[i][2];
            sum12[i] = sum12[i - 1] + note[i][1] + note[i][2];
        }    
        
        for(int i = 1;i <= n;i++)
            for(int j = 1;j <= n;j++)
            {
                for(int z = k;z >= 1;z--)
                {
                    dp[i][j][z] = max(dp[i - 1][j][z],dp[i][j - 1][z]);// 第一种
                    for(int op = 1;op <= i;op++)
                        dp[i][j][z] = max(dp[i][j][z],dp[op - 1][j][z - 1] + sum1[i] - sum1[op - 1]);//第二种 
                    for(int op = 1;op <= j;op++)
                        dp[i][j][z] = max(dp[i][j][z],dp[i][op - 1][z - 1] + sum2[j] - sum2[op - 1]);//第三种 
                    for(int op = 1;op <= min(i,j);op++)
                        dp[i][j][z] = max(dp[i][j][z],dp[op - 1][op - 1][z - 1] + sum12[min(i,j)] - sum12[op - 1]);//第四种 
                }
            }
        printf("%d",dp[n][n][k]);
        return 0;
    }
  • 相关阅读:
    PE格式第五讲,手工添加节表
    PE格式第四讲,数据目录表之导入表,以及IAT表
    PE格式第三讲扩展,VA,RVA,FA(RAW),模块地址的概念
    PE文件格式详解,第三讲,可选头文件格式,以及节表
    PE文件格式详解,第二讲,NT头文件格式,以及文件头格式
    LVS
    Haproxy
    Nginx
    MySQL入门第一天——概述、数据表与约束操作
    NoSQL入门第五天——Java连接与整合操作
  • 原文地址:https://www.cnblogs.com/luoyibujue/p/7658421.html
Copyright © 2011-2022 走看看