标签:
最大子序列:
问题描述:给定整数序列:a1,a2,a3,...an(可能有负数),求a1~an的一个子序列ai~aj,使其和最大
我们很容易想到一个O(n^2)复杂度的方法,即 i : 1--->n,并令 s = 0,然后 j : i---->n, s<---s + a[j],更新maxsum,如若想得到具体的子序列,我们可设i1,j1,更新maxsum时,同时更新下标,不过为了减少运算,我们在更新时做个判断if i1 ≠ i,i1<--i
int sub_sum(int *a,int size,int &i1,int &j1) { int i,j,s,maxsum; maxsum = a[0]; i1 = j1 = 0; for(i=0;i<size;i++) { s = 0; for(j=i;j<size;j++) { s += a[j]; if(s > maxsum) { maxsum = s; if(i1 != i) i1 = i; j1 = j; } } } return maxsum; }
我们注意到,每次在对s求和时,可能遇到部分和小于0,这样的话,显然应该舍弃前面的部分和序列,这实际上有动态规划的思想,复杂度为O(n),具体方法如下:
初设maxsum <--a[0],s=i1 = j1 = temp_i<--0,在扫描数组中,我们记下当前子序列和s,然后试图更新maxsum,j1(<---i),i1(<--temp_i,i1≠temp_i1)再判断s是否小于0,小于则置s = 0,同时更新temp_i为i+1,
#include <stdio.h> int sub_sum(int *a,int size,int &i1,int &j1) { int i,maxsum,s,temp_i; maxsum = a[0]; i1 = j1 = temp_i = 0; s = 0; for(i=0;i<size;i++) { s += a[i]; if(s > maxsum) { maxsum = s; if(temp_i != i1) i1 = temp_i; j1 = i; } if(s < 0)//此处不可用else if,因为有可能s > maxsum且s <0 { s = 0; temp_i = i+1; } } return maxsum; } int main() { int a[8] = {4,-3,-4,8,-5,7,-5,7}; int i,i1,j1; printf("%d-->%d:%d\n",i1,j1,sub_sum(a,8,i1,j1)); return 0; }
最大子矩阵:
问题描述:给定一个n*m的矩阵A,求A中的一个非空子矩阵,使这个子矩阵中的元素和最大。其中,A的子矩阵指在A中行和列均连续的一块。
思路:固定第i列到第j列的范围,寻找在这个范围内的最大子矩阵,即把每行第i列上的元素到第j列的元素分别求和,就转变为了一维的情况。由于有C(n,2)种列的组合,而求一维的子序列需要m的时间,所以,总体上时间复杂度为O(n*m*m)。
参照:http://blog.csdn.net/luxiaoxun/article/details/7438315
标签:
原文地址:http://www.cnblogs.com/520xiuge/p/5459717.html