pku 2948 Martian Mining DP (记忆化搜索)
http://poj.org/problem?id=2948
题意:
给你一个n*m的矩形方格,每个方格里面都存有一定的矿资源,要求我们在每个方格内建立传送带,将他们传送到指定的工厂,一定有两种资源一种是yeyenum ,规定这种资源只能用自东向西传送带传送到最西边的工厂否则这些资源就会丢失,第二种为bloggium,规定只能用自南向北的传送带传送到最北边的工厂生产否则这种资源也会丢失。为如何开采后传送资源使获得的资源数最多,并输出最多的开采量。
思路:
对于每一个点来说,他要么一直传送到最北边的工厂,要么传送到最西边的工厂,所以对于每一点有两种传送方式,故有状态转移方程为:
dp[i][j] = max(DP(i - 1,j) + mapy[i][j],DP(i,j - 1) + mapb[i][j]);//(i,j)点详细传送,或者想北传送。。
发现越来越喜欢记忆化搜索来写dp了。。。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <cstdio> #include <iostream> #include <cstring> #include <algorithm> #define CL(a,num) memset(a,num,sizeof(a)) #define maxn 507 #define N 8 using namespace std; const int inf = 99999999; int dp[maxn][maxn]; int mapy[maxn][maxn],mapb[maxn][maxn]; int n,m; int DP(int i,int j) { if (dp[i][j] != -1) return dp[i][j]; if (i <= 0 || i > n || j <= 0 || j > m) { dp[i][j] = 0; return 0; } dp[i][j] = max(DP(i - 1,j) + mapy[i][j],DP(i,j - 1) + mapb[i][j]); return dp[i][j]; } int main() { //freopen("din.txt","r",stdin); int i,j; while (~scanf("%d%d",&n,&m)) { if (!n && !m) break; CL(mapy,0); CL(mapb,0); for (i = 1; i <= n; ++i) { for (j = 1; j <= m; ++j) { scanf("%d",&mapy[i][j]); mapy[i][j] += mapy[i][j - 1]; } } for (i = 1; i <= n; ++i) { for (j = 1; j <= m; ++j) { scanf("%d",&mapb[i][j]); mapb[i][j] += mapb[i - 1][j]; } } CL(dp,-1); printf("%d\n",DP(n,m)); } return 0; }