拿到dp题我们就要想如何推方程
“最北边有bloggium的收集站,最西边有 yeyenum 的收集站。现在要你在这些格子上面安装向北或者向西的传送带(每个格子只能装一种)。”
这说明了什么,对于某一个点,是不是只能通过2种方式来获取这个点的值,一个是铺北的传送带,一个是铺西的传送带。然而,如果在这个点铺了传送带的话,说明整一行都会被铺,但由于后来的可以铺不同的传送带来获取该点的值,说明如果在这个点铺的话只会影响这个点的西边的点或北边的点。
综上所述,我们对于仍以一个点,需要考虑以什么形式来铺,然而会影响前面,所以我们要考虑用前缀和来维护
则可以十分轻松的推出方程
f[i][j]=max(f[i][j-1]+a[i][j],f[i-1][j]+b[i][j]);
其中a数组时i行j列向北的前缀和数组,b数组就是向西的
AC代码
1 #include <cstdio> 2 #include <algorithm> 3 4 #define MAXN 510 5 6 using namespace std; 7 8 int f[MAXN][MAXN]; 9 int a[MAXN][MAXN]; 10 int b[MAXN][MAXN]; 11 12 int n,m; 13 int temp=-1; 14 15 int main() { 16 17 while(scanf("%d%d",&n,&m)) { 18 19 if(n==0||m==0) break; 20 21 for(int i=1;i<=n;i++) 22 for(int j=1;j<=m;j++) { 23 scanf("%d",&temp); 24 b[i][j]=b[i][j-1]+temp; 25 } 26 27 for(int i=1;i<=n;i++) 28 for(int j=1;j<=m;j++) { 29 scanf("%d",&temp); 30 a[i][j]=a[i-1][j]+temp; 31 } 32 33 temp=-1; 34 35 for(int i=1;i<=n;i++) { 36 for(int j=1;j<=m;j++) { 37 f[i][j]=max(f[i][j-1]+a[i][j],f[i-1][j]+b[i][j]); 38 temp=max(f[i][j],temp); 39 } 40 } 41 42 printf("%d\n",temp); 43 } 44 return 0; 45 }
原文地址:https://www.cnblogs.com/xugangfan/p/12150042.html
时间: 2024-10-04 00:28:36