题意:在一个矿场上有两种矿石,分别对应两个处理他的工厂分别在左边与上边。要求你铺设运输设备每个方格可以向左、上或不运。矿石在运输途中不能转弯,问你最多能运多少矿石到相应的工厂加工。
思路:我们可以注意到由于不能转弯的原因,所以一旦左边的格子被铺上向左的他也也铺上向左的比较有利,否则左边的就白铺了(铺了也运不到)这样每种格子两种选择,就可以写dp方程了:
dp[i][j][0]:当前格子不铺的最大收获
dp[i][j][1]:当前格子向上的最大收获
dp[i][j][2]:当前格子向左的最大收获
F(a, b) : a = max(a, b)
G(i, j): max(dp[i][j][0], dp[i][j][1], dp[i][j][2])
dp[i][j][0]:F(dp[i][j][0], max(G(i-1,j)+mpa[i][j-1], G(i, j-1)+mpb[i-1][j]))
dp[i][j][1]:F(dp[i][j][1], max(G(i, j-1)+mpb[i][j]), dp[i-1][j][1]+mpa[i][j-1]+mpb[i][j]-mpb[i-1][j]))
dp[i][j][2]:F(dp[i][j][2], max(G(i-1, j)+mpa[i][j], dp[i][j-1][2]+mpb[i-1][j]+mpa[i][j]-mpa[i][j-1]))
代码如下:
1 /************************************************** 2 * Author : xiaohao Z 3 * Blog : http://www.cnblogs.com/shu-xiaohao/ 4 * Last modified : 2014-05-08 13:35 5 * Filename : L_1035.cpp 6 * Description : 7 * ************************************************/ 8 9 #include <iostream> 10 #include <cstdio> 11 #include <cstring> 12 #include <cstdlib> 13 #include <cmath> 14 #include <algorithm> 15 #include <queue> 16 #include <stack> 17 #include <vector> 18 #include <set> 19 #include <map> 20 #define MP(a, b) make_pair(a, b) 21 #define PB(a) push_back(a) 22 23 using namespace std; 24 typedef long long ll; 25 typedef pair<int, int> pii; 26 typedef pair<unsigned int,unsigned int> puu; 27 typedef pair<int, double> pid; 28 typedef pair<ll, int> pli; 29 typedef pair<int, ll> pil; 30 31 const int INF = 0x3f3f3f3f; 32 const double eps = 1E-6; 33 const int LEN = 1010; 34 int dp[LEN][LEN][3], n, m, mpa[LEN][LEN], mpb[LEN][LEN]; 35 36 void F(int &a, int b){ 37 a = max(a, b); 38 } 39 40 int G(int a, int b){ 41 int ret = max(dp[a][b][1], dp[a][b][2]); 42 ret = max(ret, dp[a][b][0]); 43 return ret; 44 } 45 46 int main() 47 { 48 // freopen("in.txt", "r", stdin); 49 50 int T, kase = 1, tmp; 51 scanf("%d", &T); 52 while(T--){ 53 scanf("%d%d", &n, &m); 54 memset(dp, 0, sizeof dp); 55 memset(mpa, 0, sizeof mpa); 56 memset(mpb, 0, sizeof mpb); 57 for(int i=1; i<=n; i++){ 58 for(int j=1; j<=m; j++){ 59 scanf("%d", &tmp); 60 mpa[i][j] = mpa[i][j-1] + tmp; 61 } 62 } 63 for(int i=1; i<=n; i++){ 64 for(int j=1; j<=m; j++){ 65 scanf("%d", &tmp); 66 mpb[i][j] = mpb[i-1][j] + tmp; 67 } 68 } 69 for(int i=1; i<=n; i++){ 70 for(int j=1; j<=m; j++){ 71 F(dp[i][j][0], max(G(i-1,j)+mpa[i][j-1], G(i, j-1)+mpb[i-1][j])); 72 F(dp[i][j][1], G(i, j-1)+mpb[i][j]); 73 F(dp[i][j][2], G(i-1, j)+mpa[i][j]); 74 F(dp[i][j][1], dp[i-1][j][1]+mpa[i][j-1]+mpb[i][j]-mpb[i-1][j]); 75 F(dp[i][j][2], dp[i][j-1][2]+mpb[i-1][j]+mpa[i][j]-mpa[i][j-1]); 76 } 77 } 78 printf("Case %d: %d ", kase ++, G(n, m)); 79 } 80 return 0; 81 }