矩阵取数问题,51nod1084,多路dp-CSDN博客

58 阅读1分钟

51nod1084,

两路dp,两次从(1, 1)走到(n, m),拾取路上的珍珠。

dp[k][i][j] 表示第k步时,一个人在i列,一个人在j列,i + j = k (m + n >= k >= 2)。我一般都会将输入和处理分开来,下面的solve()函数用于处理数据

#include <iostream>
#include <cstdio>
#include <queue>
#include <stack>
#include <string>
#include <cstring>
#include <map>
#include <set> 
#include <algorithm>
#include <cstdlib>
#include <cmath>
using namespace std;
#define MAX(a,b,c,d) max(max(a,b),max(c,d))
const int maxn = 200 + 7;
int pic[maxn][maxn];
int dp[maxn << 1][maxn][maxn];
void solve(int n, int m, int pic[][maxn]){
	//多路dp 
	memset(dp, 0, sizeof dp);
	for (int k = 2; k <= n + m; k++)
		for (int i = 1; i <= n && k - i > 0; i++) //k是两路列数和 
			for (int j = 1; j <= n && k - j > 0; j++)
				dp[k][i][j] =
					MAX(dp[k - 1][i][j], //下下 
						dp[k - 1][i - 1][j - 1], //右右 
						dp[k - 1][i - 1][j], //右下 
						dp[k - 1][i][j - 1]) //下右 
				+ pic[i][k - i] + (i == j ? 0 : pic[j][k - j]);				
}
int main()
{
	ios::sync_with_stdio(false);
	int m, n;//n行,m列
	while(cin >> m >> n) {
		for (int i = 1; i <=n; ++i) {
			for (int j = 1; j <= m; ++j) {
				cin >> pic[i][j];
			}
		}
		solve(n, m, pic);
		cout << dp[m +n][n][n] << endl;
	}	
	return 0;
}


\

\