nyoj 44 子串和 & nyoj 104 最大和
来源:互联网 发布:transmit mac 破解 编辑:程序博客网 时间:2024/04/30 13:49
子串和
- 描述
- 给定一整型数列{a1,a2...,an},找出连续非空子串{ax,ax+1,...,ay},使得该子序列的和最大,其中,1<=x<=y<=n。
- 输入
- 第一行是一个整数N(N<=10)表示测试数据的组数)
每组测试数据的第一行是一个整数n表示序列中共有n个整数,随后的一行里有n个整数I(-100=<I<=100),表示数列中的所有元素。(0<n<=1000000) - 输出
- 对于每组测试数据输出和最大的连续子串的和。
- 样例输入
151 2 -1 3 -2
- 样例输出
5
一道需要很注意的题。用的是贪心策略:用max保存一段区间的最大值。一边输入一边看看当前连续区间的和sum是不是大于了max,如果大了,就更新max。注意,此时的sum没有被更新,而是继续累加。这样就完成了连续区间这一要求。 可能会问:这样求的不是从第一个数开始的最大子串和么? 如果是从第二数开始的某一子串和才是最大的怎么办?这时,就要想:这些全都是数啊,如果都是正数,肯定全加起来才是最大的。但问题就是这里边会有负数。所以,从第i开始的子串和最大的情况,只可能是前i-1个数的和为负数,不然不可能舍弃这一段数的。
#include <iostream>#include <stdio.h>#include <algorithm>using namespace std;int a[1000003];int main(){ int t, n, i, sum, max; scanf("%d", &t); while(t--) { scanf("%d", &n); scanf("%d", &a[0]); sum = a[0]; max = a[0];//max一定要足够小。因为可能有负数。 if(sum < 0)//这个一定要有,不然输入-2,1……就会出错,1不能被存入了。 sum = 0; for(i = 1 ; i < n ; i++) { scanf("%d", &a[i]); sum += a[i]; if(sum > max) max = sum; if(sum < 0) sum = 0; } printf("%d\n", max); } return 0;}
最大和
- 描述
给定一个由整数组成二维矩阵(r*c),现在需要找出它的一个子矩阵,使得这个子矩阵内的所有元素之和最大,并把这个子矩阵称为最大子矩阵。
例子:
0 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2
其最大子矩阵为:9 2
-4 1
-1 8
其元素总和为15。- 输入
- 第一行输入一个整数n(0<n<=100),表示有n组测试数据;
每组测试数据:
第一行有两个的整数r,c(0<r,c<=100),r、c分别代表矩阵的行和列;
随后有r行,每行有c个整数; - 输出
- 输出矩阵的最大子矩阵的元素之和。
- 样例输入
14 40 -2 -7 0 9 2 -6 2 -4 1 -4 1 -1 8 0 -2
- 样例输出
15
利用上一题的思想,这一题也可以用类似的贪心解出来。
乍眼一看,这题和上一题差不多啊,但是怎么把二维转化为一维呢?因为要想办法把矩阵转化为一行的这种数组,所以就想到压缩,假如要求一个两行的矩阵的最大子矩阵,那么就可以先求出第一行的最大子串和,然后把数组一列对一列地叠加,更新后的t再求最大子串和,就是以第一行起始的所有矩阵的最大子矩阵了,因为最大子矩阵就是数字加起来和最大!
用i控制总循环次数,表示:这一次求的是起始行必为i,但终止行(j)和宽度(k)随意的所有矩形中最大的。这里矩形数字和的求法是在同i的条件下,用t数组保存一行,即把上几行的数组压缩成一个t,像摞饼一样- - 一层一层叠加上,列于列对应,然后求t的最大子串和,也就是被压缩的矩阵中的最大矩阵。然后求以所有起始行开始的所有最大值中的最大值即为所求。
#include <iostream>#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;int r, c, a[105][105];int findmax(int t[]){ int max = t[1], sum = 0, i; for(i = 1 ; i <= c ; i++)//必须从1开始。如果从2开始,假如是-2,1……就会出错 { sum += t[i]; if(sum > max) max = sum; if(sum < 0) sum = 0; } return max;}int main(){ int n, i, j, k, max, t[105], s; scanf("%d", &n); while(n--) { scanf("%d %d", &r, &c); for(i = 1 ; i <= r ; i++) for(j = 1 ; j <= c ; j++) scanf("%d", &a[i][j]); max = a[1][1]; for(i = 1 ; i <= r ; i++) { memset(t, 0, sizeof(t)); for(j = i ; j <= r ; j++) { for(k = 1 ; k <= c ; k++) t[k] = t[k] + a[j][k]; s = findmax(t); if(s > max) max = s; } } printf("%d\n", max); } return 0;}
- nyoj 44 子串和 & nyoj 104 最大和
- nyoj 44 子串和【最大子串和】
- nyoj 44 子串和(最大连续子序列和)
- NYOJ 44 & 104 - 最大连续子串和(矩阵最大子矩阵和)
- 计蒜客-最大子阵列 / NYOJ题目44-子串和
- NYOJ 44 子串和 && NYOJ 983 首尾相连数组的最大子数组和
- 最大子段和问题(nyoj 44 && 104)
- nyoj 44 子串和
- NYOJ-子串和44
- NYOJ 44 子串和
- nyoj-44-子串和
- NYOJ 44 子串和
- NYOJ 44 子串和
- NYOJ 44 子串和
- NYOJ 44 子串和
- NYOJ 44 子串和
- nyoj 44 子串和
- nyoj 44 子串和
- 高并发Web服务的演变——节约系统内存和CPU
- 常用css
- 解决office2010打开文件时“文件已损坏”问题
- 怎么把PDF文件分割成单独的几页
- 看数据结构写代码(13)栈的应用(四) 迷宫求解
- nyoj 44 子串和 & nyoj 104 最大和
- gcc编译器 CFLAGS 标志参数说明
- 利用BeanUtils在对象间复制属性
- linux IPC之消息队列
- vs2010 空格出现点的解决办法
- windows自定义命令的创建
- 关于jquery jqgrid 列编辑状态时获得值
- Android应用之《宋词三百首》(一)
- jQuery 方法append与after