题目链接:点击查看

题目大意:给出一个n*n的矩阵,每个点都有一个权值,现在要从中选取一个子矩阵要求权值和最大,问这个最大权值和是多少

题目分析:因为是要求子矩阵的权值和最大的问题,我们可以直接维护一个二维前缀和,然后n^4暴力求解即可,简单暴力不多说了,着重说一下另一个思想

上面的4层for分别枚举的是行起点,行终点,列起点,列终点,我们可以通过线性dp将列起点和列终点这两层for优化成一层for,具体的实现就是求一个最大连续子段和,我们可以将行起点到行终点中的所有行对应的列累加到一个一维数组中,然后求一下这个数组的最大连续子段和,就是当前枚举的行之中最大的答案了,实时维护一下最大值就好了

就是突然感觉,最大连续子段和的转移方程一下子就能自己写出来了,感觉和前两天做的那个树形dp很像,每个点都有两种选择,一种选择是接在前面的后面,另一种选择是自己重新当新的开头,当然如果前置状态对当前的贡献为正,肯定是接在前面的后面更优,但如果前置的状态为负,当然还是自己独成一个开头更优,实现很简单,有注释看起来应该不难

还有一种实现方法,更加广义一点,我们可以上升为求子段长度不小于L的最大连续子段和,这个时候我们就需要借助前缀和来实现了,转移方程就是dp[i]=sum[i]-min(sum[j]),j=[0,i-L],乍一看,时间复杂度是n*n级别的,其实不然,后面求最小值的那个部分还可以继续优化,我们不妨用一个变量mmin直接维护一下前i-L中的最小值,这样就能将时间复杂度优化至O(n)了,具体实现也很简单:

for(int i=L;i<=n;i++)

{

mmin=min(mmin,sum[i-L]);

ans=max(ans,sum[i]-mmin);

}

代码:

1:

#include<iostream>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<climits>
#include<cmath>
#include<cctype>
#include<stack>
#include<queue>
#include<list>
#include<vector>
#include<set>
#include<map>
#include<sstream>
using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=110;int n;int maze[N][N];//维护最初的矩阵int sum[N];//维护的一维矩阵int solve()//最大连续子段和
{int ans=-inf;//答案int temp=0;//当前的子段和for(int i=1;i<=n;i++){if(temp<0)//不要前面的 temp=sum[i];else//要前面的 temp+=sum[i];ans=max(ans,temp);//实时更新答案}return ans;
}int main()
{
//  freopen("input.txt","r",stdin);
//  ios::sync_with_stdio(false);while(scanf("%d",&n)!=EOF){for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)scanf("%d",&maze[i][j]);int ans=-inf;for(int i=1;i<=n;i++)//行起点 {memset(sum,0,sizeof(sum));for(int j=i;j<=n;j++)//行终点 {for(int k=1;k<=n;k++)sum[k]+=maze[j][k];ans=max(ans,solve());}}printf("%d\n",ans);}return 0;
}

2:

#include<iostream>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<climits>
#include<cmath>
#include<cctype>
#include<stack>
#include<queue>
#include<list>
#include<vector>
#include<set>
#include<map>
#include<sstream>
using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=110;int n;int maze[N][N];int sum[N];int summ[N];int solve()
{int ans=-inf;int temp=0;for(int i=1;i<=n;i++)//ssum维护sum的前缀和summ[i]=summ[i-1]+sum[i];int mmin=inf;for(int i=0;i<=n;i++){mmin=min(mmin,summ[i]);ans=max(ans,summ[i]-mmin);}return ans;
}int main()
{
//  freopen("input.txt","r",stdin);
//  ios::sync_with_stdio(false);while(scanf("%d",&n)!=EOF){for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)scanf("%d",&maze[i][j]);int ans=-inf;for(int i=1;i<=n;i++)//行起点 {memset(sum,0,sizeof(sum));for(int j=i;j<=n;j++)//行终点 {for(int k=1;k<=n;k++)sum[k]+=maze[j][k];ans=max(ans,solve());}}printf("%d\n",ans);}return 0;
}

POJ - 1050 To the Max(最大连续子段和,线性dp)相关推荐

  1. POJ 1050 To the Max (最大子矩阵和)

    题目链接 题意:给定N*N的矩阵,求该矩阵中和最大的子矩阵的和. 题解:把二维转化成一维,算下就好了. #include <cstdio> #include <cstring> ...

  2. HDU1081:To The Max(最大子矩阵,线性DP)

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1081 自己真够垃圾的,明明做过一维的这种题,但遇到二维的这种题目,竟然不会了,我也是服了(ps:猪啊). ...

  3. CodeForces - 1486D Max Median(二分+最长连续子段和)

    题目链接:点击查看 题目大意:给出一个长度为 nnn 的数列,现在从长度至少为 kkk 的连续子段中,找到最大的中位数 题目分析:做过平均数的模型:POJ - 2018 Best Cow Fences ...

  4. POJ - 2018 Best Cow Fences(二分+最长连续子段和)

    题目链接:点击查看 题目大意:给出n个正整数,求一个平均数最大的.长度不小于L的连续子段 题目分析:因为这个题目的答案满足二分的性质,也就是若二分的平均数小于答案,则更小的平均数肯定都满足答案(因为这 ...

  5. 解题报告:SP1043 GSS4 - Can you answer these queries III(GSS线段树八部曲之三)(区间最大连续子段和)

    要注意输入的数据有坑,x可能大于y- 我们可以模块化编程,使得整个代码井井有条 函数可以重名,只要参数不一样就行. 来源 yxc老师的上课板书 然后就是简单的代码了 #include<iostr ...

  6. CodeForces - 1373D Maximum Sum on Even Positions(最大连续子段和)

    题目链接:点击查看 题目大意:给出一个长度为 n 的数列 a ,允许选择一个子串进行翻转,问最后可以得到的,偶数位置的数字之和的最大值是多少 题目分析:模拟几次不难发现,我们翻转的长度必须是偶数才能有 ...

  7. CodeForces - 1359D Yet Another Yet Another Task(最大连续子段和)

    题目链接:点击查看 题目大意:选出一个连续子段和后,会减去相应区间内的最大值,问在此情况下的最大连续子段和是多少 题目分析:因为每个元素的取值很小,所以可以枚举每个元素作为最大值,然后依次求最大连续子 ...

  8. 寻找指定长度以内的最短连续子段和

    寻找指定长度以内的最短连续子段和 沟里学姐的残忍 ★实验任务 现在沟里学姐有一把激光刀,现在有 n 个人站在一排(每隔一米站一个人), 沟里对每个人都有一个仇恨值 ai (仇恨值可正可负,因为有些人可 ...

  9. 严格递增最大连续子段(思维)

    严格递增最大连续子段 时间限制: 1 Sec  内存限制: 128 MB 提交: 88  解决: 8 [提交][状态][讨论版] 题目描述 给定n个非负元素,你最多可以改变一个元素为任意整数.问可以得 ...

最新文章

  1. js如何关闭当前页,而不弹出提示框
  2. oracle 收回 user,oracle 10.2.0.3对USER收回CONNECT及RESOURCE
  3. 《JAVA与模式》之命令模式
  4. MyBatis+Spring整合
  5. 让我们来开发一种更类似人脑的神经网络吧(三)
  6. 《云栖精选》第8期:科技,改变世界
  7. Delphi 2009 新增的 Class Explorer
  8. java 数据 权限_Java如何利用Mybatis进行数据权限控制详解
  9. Notepad++快速选中多行
  10. webservice无法理解soap头action_数学是对理解的追求,而不仅仅是追求计算
  11. UOS设置屏幕缩放后的配置文件研究
  12. WireGuard简单配置
  13. Java实现一个学生类Student
  14. Java超实用工具分享,excel填充、m3u8格式合成MP4...
  15. 计算机专业技术个人小结,计算机专业技术个人小结.doc
  16. excel单元格斜线_制作excel双斜线表头的新方法,完美解决拖动变形的问题
  17. Godaddy域名申请及设置
  18. 电影票在线选座API接口电影排期场次
  19. 文档生成工具-Doxygen使用方法以及注释规则
  20. 爬虫破解安居客等网址信息字体加密

热门文章

  1. MySQL【案例讲解】单行函数
  2. 如何选择合适的垃圾收集器
  3. Java领域的对象如何传输-如何解决报错的问题呢?
  4. MapReduce-Combiner规约-原理分析
  5. shiro的会话管理:介绍
  6. Spring Cloud Gateway-ServerWebExchange核心方法与请求或者响应内容的修改
  7. int型数据占用的内存空间及ASCII码表
  8. IDEA报错:Loading class `com.mysql.jdbc.Driver‘. This is deprecated. The new driver class is `com.mysql
  9. Makefile(直接可以使用)
  10. 理解单例模式、单例类