一、最大子序列和
问题定义:对于给定序列 a1,a2,a3……an 寻找它的连续的最大和子数组。
用数组 dp[i] 来保存当前最大的连续子数组,循环遍历每个数,然后每次检验 dp[i-1] 是否大于零,只要大于零就令 dp[i] = dp[i-1]+a[i] ,如果 dp[i-1]<0 ,那么直接令 dp[i]=a[i]
for(int i=2;i<=n;i++)
{
if(dp[i-1]>=0)
dp[i]=dp[i-1]+a[i];
else
dp[i]=a[i];
}
二、最大子矩阵和
问题定义:给定一个 n 行 m 列的整数矩阵 A,现在要求 A 的一个子矩阵,使其各元素之和为最大。
最后子矩阵一定是在某两行之间的,假设子矩阵在第 i 行和第 j 行之间,那么我们可以枚举所有1<=i<=j<=n,表示最终子矩阵选取的行范围。
将每一列第 i 行到第 j 行之间的和求出来,形成一个数组 c,于是一个第 i 行到第 j 行之间的最大子矩阵和对应于这个和数组 c 的最大子段和。
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
int temp;
cin>>temp;
a[i][j]=a[i-1][j]+t; //a[i][j]存的是第j列到第i行为止所有元素的和
}
}
int ans=-INF;
for(int i=1;i<=n;i++){
for(int j=i;j<=n;j++){ //枚举所有的行区间
int sum=0;
for(int k=1;k<=m;k++){ //枚举这个区间里的所有列
sum+=a[j][k]-a[i-1][k]; //先加上这一小竖列
if(sum<0) //小于0了,归零从下一个来
sum=0;
if(sum>ans)
ans=sum; //更新最大矩阵和
}
}
}
三、左上走到右下或者三角形
很基础~~~~
代码的模板就是从小遍历到大
矩阵:要么是从上边走来的(a[i-1][j])要么是从左边走来的(a[i][j-1])
数字三角形:要么是从左上边走来的(a[i-1][j-1]),要么是从右上边走来的(a[i-1][j])