题目见洛谷(https://www.luogu.org/problem/show?pid=2380)
比较好想的一道动态规划的题目可以用而为前缀和先处理出来,这样子部分区间时间复杂度好像是变大啦,但是其实总的时间复杂度其实相比前面是变小了不知道二位前缀和的同学自己百度一下吧
小小贴一下处理前缀和的代码吧:
for(R int i=1;i<=n;i++){
for(R int j=1;j<=m;j++){
a[i][j]=read(),a[i][j]+=a[i][j-1];
}
}
for(R int i=1;i<=n;i++){
for(R int j=1;j<=m;j++){
b[i][j]=read(),b[i][j]+=b[i-1][j];
}
}
这里的R是register,把对此使用的变量扔到寄存器里跑的更快QAQ
之后呢状态转移方程列一下吧:f[i][j]=max(f[i-1][j]+a[i][j],f[i][j-1]+b[i][j])其实听好想的然后时间复杂度大概是O(n*m)的,其实跑的也不算慢再加上快读快输还有register反正代码跑的挺快的,最后贴一下代码吧:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<list>
#include<queue>
#define R register
using namespace std;
int n,m,a[2000][2000],b[2000][2000],f[2000][2000];
inline int read(){
int num;
char ch;
while((ch=getchar())<'0' || ch>'9');
num=ch-'0';
while((ch=getchar())>='0' && ch<='9'){
num=num*10+ch-'0';
}
return num;
}
inline void out(int x){
if(x>=10){
out(x/10);
}
putchar(x%10+'0');
}
int main(){
n=read();
m=read();
if(m+n==0)return 0;
for(R int i=1;i<=n;i++){
for(R int j=1;j<=m;j++){
a[i][j]=read(),a[i][j]+=a[i][j-1];
}
}
for(R int i=1;i<=n;i++){
for(R int j=1;j<=m;j++){
b[i][j]=read(),b[i][j]+=b[i-1][j];
}
}
for(R int i=1;i<=n;i++){
for(R int j=1;j<=m;j++){
f[i][j]=max(f[i-1][j]+a[i][j],f[i][j-1]+b[i][j]);
}
}
out(f[n][m]);
return 0;
}
这道题所有点624ms就可以A掉了