题目链接:
https://www.51nod.com/onlineJudge/submitDetail.html#!judgeId=407086
题解:
最大字段和的变形
代码:
#include <cmath>
#include <cstdio>
#include <string>
#include <cstring>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
#define met(a,b) memset(a,b,sizeof(a))
#define inf 0x3f3f3f3f
typedef long long ll;
const int maxn = 500+10;
ll dp[maxn][maxn];
int main()
{
int n,m;
scanf("%d%d",&m,&n);
met(dp,0);
ll num;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
scanf("%lld",&num);
dp[i][j]=dp[i-1][j]+num;
// 对于每一列进行前缀和的操作
}
}
ll MAX=0;
ll ans=0;
for(int i=1;i<=n;i++)
{
for(int j=i;j<=n;j++)
{
// 确定任意的两行,通过前面的前缀和,相当于把这些在i,j之间的行,优化成一行
ans=0;
for(int k=1;k<=m;k++)
// 然后进行常规的最大子序列求和就行了
{
ans+=dp[j][k]-dp[i-1][k];
if(ans<0)
ans=0;
else
MAX=max(MAX,ans);
}
}
}
printf("%lld\n",MAX);
}