{5,-3,4,2} ,最大连续子序列和为8
设第 i 个数的最大连续子序列和为f[i],
f[i]=max(f[i-1]+a[i],a[i]);
最后对f数组取最大值
openjudge里的一道题
http://noi.openjudge.cn/ch0406/1768/
这是个二维数组,二维数组与一维数组求解的最大差别在于二维数组需要考虑这个矩阵有几行
不妨假设行数为 i~j ,
- 当i=j时,就是一维数组求解,选中的连续序列区间即为你选了哪几列
例如
0 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2
当i=j=1的时候,可选数为{0,-2,7,0},很显然最大和序列为{7,0},也就相当于选了3,4列的值
- 当i!=j 时,直接将第k列压缩为(1~k)列值的和,即为
a[i][j]+=a[i-1][j]
i~j 行的每列和即为a[i][j] = a[j][ k] - a[i-1][k] (k为列数)
-
转换成 i=j 的形式求解,在求解过程中就是进行选择列数
-
例如当i=2,j=3,压缩维度后即为
-
5 3 -10 3
-
最大子序列为{5,3}
-
相当于选择
-
9 2
-
-4 1
-
所以我们只需枚举行的组合,即可求解
-
附上此题的代码
-
#include<iostream> #include<string> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; int a[110][110]; int main(){ int n; scanf("%d",&n); int b; for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ scanf("%d",&a[i][j]); a[i][j]+=a[i-1][j]; } } int maxn=-12708; for(int i=1;i<=n;i++){ for(int j=i;j<=n;j++){ int f[n+1]={0}; for(int k=1;k<=n;k++){ int b=a[j][k]-a[i-1][k]; f[k]=max(f[k-1]+b,b); if(maxn<f[k]){ maxn=f[k]; } } } } cout<<maxn; return 0; }