由于状态只与前一次有关,所以用了滚动数组优化。
代码如下:
#include <stdio.h> #include <string.h> #define MS0(X) memset(X, 0, sizeof(X)) #define REP(i, a, b) for(int i = a; i <= b; ++i) typedef long long ll; const int O = 1005; const int mod = 9999991; int col[2][O], row[2][O], cnt[2][O], C[O][O], cur; int n, m, k, x, y, t, cas; void work(){ scanf("%d%d%d%d%d", &n, &m, &k, &x, &y); MS0(col); MS0(row); MS0(cnt); cur = 0; col[0][y] = row[0][x] = cnt[0][0] = cnt[1][0] = 1; REP(i, 1, k){ cur ^= 1; MS0(col[cur]); MS0(row[cur]); REP(j, 1, m){ if(j - 2 >= 1) col[cur][j] += col[cur ^ 1][j - 2]; if(j - 1 >= 1) col[cur][j] += col[cur ^ 1][j - 1]; if(j + 1 <= m) col[cur][j] += col[cur ^ 1][j + 1]; if(j + 2 <= m) col[cur][j] += col[cur ^ 1][j + 2]; col[cur][j] %= mod; cnt[0][i] = (cnt[0][i] + col[cur][j]) % mod; } REP(j, 1, n){ if(j - 2 >= 1) row[cur][j] += row[cur ^ 1][j - 2]; if(j - 1 >= 1) row[cur][j] += row[cur ^ 1][j - 1]; if(j + 1 <= n) row[cur][j] += row[cur ^ 1][j + 1]; if(j + 2 <= n) row[cur][j] += row[cur ^ 1][j + 2]; row[cur][j] %= mod; cnt[1][i] = (cnt[1][i] + row[cur][j]) % mod; } } ll ans = 0; REP(i, 0, k){ ans = (ans + (((ll) cnt[0][i] * cnt[1][k - i]) % mod) * C[k][i]) % mod; } printf("%I64d\n", ans); } int main(){ REP(i, 0, O - 1) C[i][0] = 1; REP(i, 1, O - 1) REP(j, 1, i) C[i][j] = (C[i - 1][j - 1] + C[i - 1][j]) % mod; for(scanf("%d", &t), cas = 1; cas <= t; ++cas){ printf("Case #%d:\n", cas); work(); } return 0; }