您的位置:首页 > 其它

算法题2 动态规划之最大子序列和&最大子矩阵和

2016-01-27 14:05 405 查看
题目

有整数数组int a[]={-1,2,-3,10,-4,7,2,5},找出此数组的一个连续子序列,使得该子序列的和最大。可以得到子序列{10,-4,7,2,5}的和20最大,输出该子序列

分析

设sum[i]为0到i元素数组的最大子序列和,那么sum[i-1]是它的子问题解,可以利用动态规划求解。有关系式

sum[0]=a[0];

sum[i]=a[j],当sum[i-1]<0;

sum[i]=sum[i-1]+a[j],当sum[i-1]>=0;

算法复杂度为O(n),空间复杂度O(1)

代码

int MaxSubSumOfArray(int arr[],int len,int& sub_s,int& sub_e)
{
if (arr==NULL||len<=0)
{
throw std::exception("Invalid input.");
}

int sum=arr[0];
int max=sum;
int sidx=0,eidx=0;
for(int i=1;i<len;i++)
{
if(sum<0)
{
sum=arr[i];
sidx=i;
eidx=i;
}else
{
sum=sum+arr[i];
eidx++;
}
//max=(max>sum)?max:sum;
if (max<=sum)
{
max=sum;
sub_s=sidx;
sub_e=eidx;
}

}
return max;
}


  

题目

现有矩阵:


0, -2, -7, 0, 3


9, 2, -6, 2, 5


-4, 1, -4, 1, 6


-1, 8, 0, -2, 2


求该矩阵的一个子矩阵,使子矩阵所有元素的和最大


分析

对于最大子矩阵和sum来说,是子矩阵所有元素相加的和,即可以先同一列上的元素相加,多行降维成一行,进而可以转化为求最大子序列和的问题。循环对矩阵不同行的组合进行降维求最大子序列和,进而求出和最大的那个行组合,即可得到最大子矩阵和。

算法时间复杂度O(n*n*m)

代码

int MaxSumOfMatrix(int **matrix,int row_len,int column_len)
{
if (matrix==NULL||row_len<=0||column_len<=0)
{
throw std::exception("Invalid input.");
return -1;
}

int max=0;

//申请二维数组空间
int **sumMatrix=new int*[row_len];
for (int i=0;i<row_len;i++)
{
sumMatrix[i]=new int[column_len]();
}

//依次求0到i列累加和
for (int row=0;row<row_len;row++)
{
for (int col=0;col<column_len;col++)
{
if (row==0)
{
sumMatrix[row][col]=matrix[row][col];
}else
{
sumMatrix[row][col]=sumMatrix[row-1][col]+matrix[row][col];
}

}
}

int* tmp_arr=new int[column_len]();
for (int row=0;row<row_len;row++)
{
for (int rowx=row;rowx<row_len;rowx++)
{
for (int col=0;col<column_len;col++)
{
if (row>0)
{
tmp_arr[col]=sumMatrix[rowx][col]-sumMatrix[row-1][col];
}else
{
tmp_arr[col]=sumMatrix[rowx][col];
}
}

int col_s=0,col_e=0;
int re=MaxSumOfArray2(tmp_arr,column_len,col_s,col_e);
max=(max>re)?max:re;
}
}

//释放
for (int i=0;i<row_len;i++)
{
delete[] sumMatrix[i];
}
delete[] sumMatrix;

delete[] tmp_arr;

return max;
}


 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: