luogu1006 传纸条

题目大意

小渊坐在矩阵的左上角,坐标 (1,1 ),小轩坐在矩阵的右下角,坐标 (m,n) 。从小渊传到小轩的纸条只可以向下或者向右传递,从小轩传给小渊的纸条只可以向上或者向左传递。

在活动进行中,小渊希望给小轩传递一张纸条,同时希望小轩给他回复。班里每个同学都可以帮他们传递,但只会帮他们一次,也就是说如果此人在小渊递给小轩纸条的时候帮忙,那么在小轩递给小渊的时候就不会再帮忙。反之亦然。

还有一件事情需要注意,全班每个同学愿意帮忙的好感度有高有低(注意:小渊和小轩的好心程度没有定义,输入时用 0 表示),可以用一个 0100 的自然数来表示,数越大表示越好心。小渊和小轩希望尽可能找好心程度高的同学来帮忙传纸条,即找到来回两条传递路径,使得这 2 条路径上同学的好心程度之和最大。现在,请你帮助小渊和小轩找到这样的 2 条路径。

思路

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int MAX_ROW = 60, MAX_COL = 60, MINF = 0xcfcfcfcf;
int A[MAX_ROW][MAX_COL], F[MAX_ROW][MAX_COL][MAX_ROW][MAX_COL];
int TotRow, TotCol;

const int Delta[4][4] = 
{
	{1,0,1,0},
	{1,0,0,1},
	{0,1,1,0},
	{0,1,0,1}
};

int Dfs(int row1, int col1, int row2, int col2)
{
	if (row1 == row2 && col1 == col2 && row1 == TotRow && col1 == TotCol)
		return 0;
	if (row1 == row2 && col1 == col2 && (row1 != 1 || row2 != 1 || col1 != 1 || col2 != 1) && (row1 != TotRow || col1 != TotCol))
		return MINF;
	if (row1 > TotRow || col1 > TotCol || row2 > TotRow || col2 > TotCol)
		return MINF;
	if (F[row1][col1][row2][col2] != -1)
		return F[row1][col1][row2][col2];
	for (int i = 0; i < 4; i++)
		F[row1][col1][row2][col2] = max(F[row1][col1][row2][col2], Dfs(row1 + Delta[i][0], col1 + Delta[i][1], row2 + Delta[i][2], col2 + Delta[i][3]) + A[row1][col1] + A[row2][col2]);
	return F[row1][col1][row2][col2];
}

int main()
{
	scanf("%d%d", &TotRow, &TotCol);
	for (int i = 1; i <= TotRow; i++)
		for (int j = 1; j <= TotCol; j++)
			scanf("%d", &A[i][j]);
	memset(F, -1, sizeof(F));
	printf("%d\n", Dfs(1, 1, 1, 1));
}

  

猜你喜欢

转载自www.cnblogs.com/headboy2002/p/9371307.html