luogu 题解 P2380 【狗哥采矿】

拿到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 }

猜你喜欢

转载自www.cnblogs.com/xugangfan/p/12150042.html
今日推荐