最大子序列的和
样例:
1 -3 5 -3 8 9 4 6 -4 9 9 -9 -7 9 6
#include<iostream>
using namespace std;
int main()
{
int n=15,sum=0,tmp=0;
int a[n+1];
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++)
{
tmp+=a[i];
if(tmp<0) tmp=0;
sum=max(sum,tmp);
}
cout<<sum;//最大子序列的和
return 0;
}
//寻找最大子序列所有的元素
//(该方法仅供参考,不保证其正确性)
#include<iostream>
using namespace std;
int main()
{
int n=15,sum=0,tmp=0;
int x=0,y=0;//用x,y分别来标记最大子序列的第一个与最后一个的下标
int a[n+1];
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++)
{
tmp+=a[i];
if(tmp<0)
{
tmp=0;
x=i+1;
}
if(sum<tmp)
{
sum=tmp;
y=i;
}
}
cout<<sum<<endl;
cout<<x<<" "<<y<<endl;
for(int i=x;i<=y;i++) cout<<a[i]<<" ";
return 0;
}
最大子矩阵的和
样例:
一个n*m的矩阵
4 4
0 -2 -7 0 (1)
9 2 -6 2 (2)
-4 1 -4 1 (3)
-1 8 0 -2 (4)
求 最大子矩阵的和 的原理就是:把矩阵转换成序列
枚举所有的情况:求最大子序列的和
上述的矩阵就能够转换成下面的情况
1. 0 -2 -7 0 (1)
2. 9 2 -6 2 (2)
3. -4 1 -4 1 (3)
4. -1 8 0 -2 (4)
5. 9 0 -13 2 (1+2)
6. 5 3 -10 3 (2+3)
7. -5 9 -4 -1 (3+4)
8. 5 1 -17 3 (1+2+3)
9. 4 11 -10 1 (2+3+4)
10. 4 9 -17 1 (1+2+3+4)
#include<iostream>
using namespace std;
const int N=10000;
int n,m;
int a[N][N];
//由于二维数组可定义的数据范围比较小,所以我们可以采用vector
//vector<vector<int>> a(n+1,vector<int>(m+1));
int c[N];
int main()
{
int sum=0;
int tmp,ans,i,j,k;
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>a[i][j];
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
{
//if(i==1) a[i-1][j]=0; 如果使用vector;
a[i][j]+=a[i-1][j];//基于前缀和原理
}
//使用for循环枚举所有的情况
for(i=1;i<=n;i++)
{
for(j=i;j<=n;j++)
{
//每枚举出一种情况,寻找最大子序列的和
for(k=1;k<=m;k++) c[k]=a[j][k]-a[i-1][k];
tmp=0,ans=0;
for(k=1;k<=m;k++)
{
tmp+=c[k];
if(tmp<0) tmp=0;
ans=max(ans,tmp);
}
sum=max(sum,ans);
}
}
cout<<sum;
return 0;
}