洛谷1373 小a和uim之大逃离

原题链接

只要想好状态,这题就是水题了,转移方程完全没难度。。
(f[i][j][w][u])表示走到((i, j))格,小(a)(uim)所取得魔力值的差值为(w),该格由((u = 0)则小(a)取,(u = 1)(uim)取)时的总方案数。
设格子((i, j))的魔力值为(a[i][j]),则有状态转移方程:

(qquadqquad f[i][j][w][0] = f[i][j][w][0] + f[i - 1][j][v][1] + f[i][j - 1][v][1],quad v = (w - a[i][j] + k + 1) \% (k + 1))

(qquadqquad f[i][j][w][1] = f[i][j][w][1] + f[i - 1][j][v][0] + f[i][j - 1][v][0],quad v = (w + a[i][j]) \% (k + 1))

因为小(a)能从任意一个格子开始走,所以初值为(i = 1 o n, j = 1 o m, f[i][j][a[i][j]][0] = 1)
最后答案为(sumlimits_{i = 1}^nsumlimits_{j = 1}^m f[i][j][0][1])

#include<cstdio>
using namespace std;
const int N = 810;
const int M = 16;
const int mod = 1e9 + 7;
int f[N][N][M][2], a[N][N];
inline int re()
{
	int x = 0;
	char c = getchar();
	bool p = 0;
	for (; c < '0' || c > '9'; c = getchar())
		p |= c == '-';
	for (; c >= '0' && c <= '9'; c = getchar())
		x = x * 10 + c - '0';
	return p ? -x : x;
}
inline long long MOD(long long x)
{
	if (x < mod)
		return x;
	return x - mod;
}
int main()
{
	int i, j, n, m, k, o, w, v, s = 0;
	n = re();
	m = re();
	k = re();
	o = k + 1;
	for (i = 1; i <= n; i++)
		for (j = 1; j <= m; j++)
		{
			a[i][j] = re();
			f[i][j][a[i][j]][0] = 1;
		}
	for (i = 1; i <= n; i++)
		for (j = 1; j <= m; j++)
			for (w = 0; w <= k; w++)
			{
				v = (w - a[i][j] + o) % o;
				f[i][j][w][0] = MOD(MOD(1LL * f[i - 1][j][v][1] + f[i][j - 1][v][1]) + f[i][j][w][0]);
				v = (w + a[i][j]) % o;
				f[i][j][w][1] = MOD(MOD(1LL * f[i - 1][j][v][0] + f[i][j - 1][v][0]) + f[i][j][w][1]);
				if (!w)
					s = MOD(1LL * s + f[i][j][0][1]);
			}
	printf("%d", s);
	return 0;
}
原文地址:https://www.cnblogs.com/Iowa-Battleship/p/9829949.html