这两个题本质是一个亚子,所以放一起啦
DPDPDPDPDPDPDPDP
P1115 最大子段和

题解
因为题目要求的是一段连续的区间,所以前缀和搞暴力???
我们设置数组 f[ i ] 表示以 a[ i ] 结尾的最大连续子段和
那么转移???
1.接着上一段,继续构成一段连续的子段 continue the old life
2.自成一段 和过去 say goodbye
转移方程: 
ans记录最大值就好啦
代码
#include<bits/stdc++.h>
using namespace std;
inline int read()
{
int ans=0;
char last=' ',ch=getchar();
while(ch<'0'||ch>'9') last=ch,ch=getchar();
while(ch>='0'&&ch<='9') ans=ans*10+ch-'0',ch=getchar();
if(last=='-') ans=-ans;
return ans;
}
const int maxn=2e5+10;
int n,ans;
int a[maxn];
int f[maxn];
int main()
{
n=read();
for(int i=1;i<=n;i++)
a[i]=read();
f[0]=0;f[1]=a[1];
ans=a[1];
for(int i=1;i<=n;i++)
{
f[i]=max(f[i-1]+a[i],a[i]);
ans=max(ans,f[i]);
}
printf("%d\n",ans);
return 0;
}
P1719 最大加权矩形
题解
其实这个题就是上一个的变式,我们只需要把本题的二维转变成一维就好啦!
考虑枚举子矩阵的上下界
确定了上下界,就缩成了一维,此时只需要算 “该行” ,的最大 f[ ] 就好啦!
解释一下数组:
a[ i ][ j ] :读入给出的矩阵
sum[ i ][ j ] :第 j 列,前 i 行的前缀和

其实这里的
就相当于上一个题的
代码
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
inline int read()
{
int ans=0;
char last=' ',ch=getchar();
while(ch<'0'||ch>'9') last=ch,ch=getchar();
while(ch>='0'&&ch<='9') ans=ans*10+ch-'0',ch=getchar();
if(last=='-') ans=-ans;
return ans;
}
const int maxn=125;
int n,ans=-128;
int a[maxn][maxn],sum[maxn][maxn],f[maxn];
int main()
{
n=read();
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
a[i][j]=read(),sum[i][j]=sum[i-1][j]+a[i][j];
for(int i=1;i<=n;i++)
for(int j=i;j<=n;j++) //枚举上下界 i~j
{
memset(f,0,sizeof(f));
for(int k=1;k<=n;k++) //DP
f[k]=max(f[k-1]+(sum[j][k]-sum[i-1][k]),(sum[j][k]-sum[i-1][k])),
ans=max(ans,f[k]);
}
printf("%d",ans);
return 0;
}