To the Max( POJ - 1050,子矩阵最大和 模拟 || 降维 + 最大子段和)

一.题目链接:

POJ-1050

二.题目大意:

给一个 n × n 的矩阵,求子矩阵的最大和.

三.分析:

第一种思路就是打表,然后用容斥求最大和.

详情请跳转 最大子矩阵(HDU - 1559,前缀和)

复杂度:

第二种思路是枚举 起始行 和 终止行

然后利用降维的思想,把两行之间的列向量和求出来,再求一下最大子段和取最大值即可.

复杂度:

四.代码实现:

思路一:

#include <set>
#include <map>
#include <ctime>
#include <queue>
#include <cmath>
#include <stack>
#include <vector>
#include <cstdio>
#include <sstream>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define eps 1e-6
#define pi acos(-1.0)
#define ll long long int
using namespace std;

const int M = (int)1e2;
const int inf = 0x3f3f3f3f;
const int mod = 1000000000;

int mp[M + 5][M + 5];
int sum[M + 5][M + 5];

int main()
{
    int n;
    scanf("%d", &n);
    for(int i = 1; i <= n; ++i)
        for(int j = 1; j <= n; ++j)
            scanf("%d", &mp[i][j]);
    for(int i = 1; i <= n; ++i)
        for(int j = 1; j <= n; ++j)
            sum[i][j] = sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + mp[i][j];
    int ans = -inf;
    for(int i = 1; i <= n; ++i)
        for(int j = 1; j <= n; ++j)
            for(int k = i; k <= n; ++k)
                for(int l = j; l <= n; ++l)
                    ans = max(ans, sum[k][l] - sum[i - 1][l] - sum[k][j - 1] + sum[i - 1][j - 1]);
    printf("%d\n", ans);
    return 0;
}

思路二:

#include <set>
#include <map>
#include <ctime>
#include <queue>
#include <cmath>
#include <stack>
#include <vector>
#include <cstdio>
#include <sstream>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define eps 1e-6
#define pi acos(-1.0)
#define ll long long int
using namespace std;

const int M = (int)1e2;
const int inf = 0x3f3f3f3f;
const int mod = 1000000000;

int dp[M + 5];
int col[M + 5];
int mp[M + 5][M + 5];

int get_sum(int n)///最大子段和
{
    int ans = -inf;
    memset(dp, 0, sizeof(dp));
    for(int i = 1; i <= n; ++i)
    {
        dp[i] = max(dp[i - 1] + col[i], col[i]);
        ans = max(ans, dp[i]);
    }
    return ans;
}

int main()
{
    int n;
    scanf("%d", &n);
    for(int i = 1; i <= n; ++i)
        for(int j = 1; j <= n; ++j)
            scanf("%d", &mp[i][j]);
    int ans = -inf;
    for(int i = 1; i <= n; ++i)
    {
        memset(col, 0, sizeof(col));
        for(int j = i; j <= n; ++j)
        {
            for(int k = 1; k <= n; ++k)
                col[k] += mp[j][k];///求列向量和
            ans = max(ans, get_sum(n));
        }
    }
    printf("%d\n", ans);
    return 0;
}

 

全部评论

相关推荐

12-06 01:10
已编辑
哈尔滨工程大学 Java
一面问的真细,二面不知为啥变双机位。9.29快手主站平时怎么学习&nbsp;AI&nbsp;的,国内外知名大模型,实习公司都用的什么大模型,怎么评估效果的java池化思想,线程池构造方法的核心参数,线程池中阻塞队列注意事项,submit方法参数和执行逻辑,shutdown和shutdownnow,核心线程允许过期吗threadlocal底层,为什么key是弱引用,key回收了再get或者set这个value会怎样aqs,如何保证公平性java代理java堆划分,新生代还有别的晋升老年代的情况吗,什么时候触发gc,gc失败抛什么异常,如何排查oom,导出dump命令redis数据结构,哪个底层是跳表,和其他数据结构对比布隆过滤器会出现大key问题吗,你咋实现的布隆过滤器你怎么实现redis分布式锁,可重入,续期聚簇索引非聚簇索引select语句会加锁吗,怎么实现的不加锁undolog&nbsp;redolog&nbsp;binlog怎么能让select加锁,update这个范围加的什么锁,update一条呢手撕简单01背包,接雨水10.10快手主站意图识别用的哪个大模型,走到意图和rag的比例,faq是点击的吗自然语言怎么识别的gap一年干啥了,转正怎么样没跟组里提意向吗,研究生研究方向是传统算法吗,会大模型微调吗注册场景为什么用布隆过滤器,原理分布式锁底层的key怎么拼的,value里是什么redis持久化zset底层mysql索引结构,一个表三个字段有主键唯一索引和没索引的字段会有几个b+树,聚簇索引非聚簇索引存的啥无手撕
点赞 评论 收藏
分享
今天 09:59
复旦大学 Java
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务