luoguP5003 跳舞的线-乱转弯

下面讨论最大值,最小值类似.

\(f[i][j][0/1]\)表示从右或上走到\((i,j)\)时最大拐弯数.

\[\therefore f[i][j][k]=\begin{cases}\max(f[i][j][k],\max(f[i-dx[k]][j-dy[k]][k],f[i-dx[k]][j-dy[k]][!k]+1)))&map[i][j]='\!o'\\-inf&map[i][j]!='\!\#'\end{cases} \]

#pragma GCC optimize(3)
#include<bits/stdc++.h>
#define il inline
#define rg register
#define gi read<int>
using namespace std;
const int O = 1e3 + 10;
const int dx[2] = {1, 0}, dy[2] = {0, 1};
template<class TT>
il TT read() {
	TT o = 0, fl = 1; char ch = getchar();
	while (!isdigit(ch)) fl ^= ch == '-', ch = getchar();
	while (isdigit(ch)) o = o * 10 + ch - '0', ch = getchar();
	return fl ? o : -o;
}
bool v[O][O];
int n, m, fx[O][O][2], fy[O][O][2];
char s[O];
int main() {
	n = gi(), m = gi();
	for (int i = 1; i <= n; ++i) {
		scanf("%s", s + 1);
		for (int j = 1; j <= n; ++j)
			v[i][j] = s[j] == '#';
	}
	if (v[1][1]) return 0 & puts("-1");
	memset(fx, -127, sizeof fx);
	memset(fy, 127, sizeof fy);
	fx[1][1][0] = fy[1][1][0] =	fx[1][1][1] = fy[1][1][1] = 0;
	for (int i = 1; i <= n; ++i)
		for (int j = 1; j <= m; ++j)
			if(v[i][j] ^ 1)
				for (int k = 0; k <= 1; ++k) {
					fx[i][j][k] = max(fx[i][j][k],max(fx[i - dx[k]][j - dy[k]][k], fx[i - dx[k]][j - dy[k]][k ^ 1] + 1));
					fy[i][j][k] = min(fy[i][j][k],min(fy[i - dx[k]][j - dy[k]][k], fy[i - dx[k]][j - dy[k]][k ^ 1] + 1));
				}
	if (max(fx[n][m][0], fx[n][m][1]) == fx[0][0][0]) return 0 & puts("-1");
	printf("%d %d\n", max(fx[n][m][0], fx[n][m][1]) - 1, min(fy[n][m][0], fy[n][m][1]));
	return 0;
}

posted @ 2019-10-13 23:08  wuhan2005  阅读(104)  评论(0编辑  收藏  举报