POJ 2948 Martian Mining [DP]
题意:不想复述了。。好累。。
思路:yey矿只能由东向西运送,用数组yey[i][j]表示地图中从(i, 1), (i, 2), ... 到 (i, j)的yey矿总量。blog矿只能由南向北运送,用数组blog[i][j]表示地图中从(1, j), (2, j), ... 到 (i, j)的blog矿总量。
而dp[i][j]表示左上顶点为(1, 1),右下顶点为(i, j)的矩形内按照题意可运送的矿产总量的最大值。则关键点就是位于(i, j)处的矿产。可以有两种选择,一种是从该点建一条向北的blog矿的传送带,另一种是从该点建一条向西的yey矿的传送带。由此可得dp的递推公式:
dp[i][j] = max(dp[i][j-1] + blog[i][j], dp[i-1][j] + yey[i][j]).
1 #include<stdio.h> 2 #include<algorithm> 3 #include<string.h> 4 #define maxn 505 5 using namespace std; 6 int yey[maxn][maxn], blog[maxn][maxn]; 7 int dp[maxn][maxn]; 8 int main() 9 { 10 int n, m; 11 //freopen("data.in", "r", stdin); 12 while (~scanf("%d%d",&n,&m) && n && m) 13 { 14 memset(yey, 0, sizeof(yey)); 15 memset(blog, 0, sizeof(blog)); 16 memset(dp, 0, sizeof(dp)); 17 for (int i = 1; i <= n; i++) 18 for (int j = 1; j <= m; j++) 19 { 20 int a; 21 scanf("%d",&a); 22 yey[i][j] = yey[i][j-1] + a; 23 } 24 for (int i = 1; i <= n; i++) 25 for (int j = 1; j <= m; j++) 26 { 27 int a; 28 scanf("%d",&a); 29 blog[i][j] = blog[i-1][j] + a; 30 } 31 for (int i = 1; i <= n; i++) 32 for (int j = 1; j <= m; j++) 33 dp[i][j] = max(dp[i][j-1] + blog[i][j], dp[i-1][j] + yey[i][j]); 34 printf("%d\n",dp[n][m]); 35 } 36 return 0; 37 }