classSolution { private: staticconstexprint T = 243, N = 5, M = 6; int n, m, tot; int mask_bits[T][N]; int iv_count[T], ev_count[T]; int inner_score[T], inter_score[T][T]; int d[N][T][M + 1][M + 1];
intdfs(int row, int premask, int iv, int ev, int m, int tot) { if (row == m || (iv == 0 && ev == 0)) { return0; } // 如果该状态已经计算过答案,则直接返回 if (d[row][premask][iv][ev] != -1) { return d[row][premask][iv][ev]; } // 使用引用,简化代码 int *res = &d[row][premask][iv][ev]; // 合法状态,初始值为 0 *res = 0; for (int mask = 0; mask < tot; mask++) { // mask 包含的内向人数不能超过 iv ,外向人数不能超过 ev if (iv_count[mask] > iv || ev_count[mask] > ev) { continue; } *res = fmax(*res, dfs(row + 1, mask, iv - iv_count[mask], ev - ev_count[mask], m, tot) + inner_score[mask] + inter_score[premask][mask]); } return *res; }
voidinit_data(int m, int n, int tot) { memset(mask_bits, 0, sizeof(mask_bits)); memset(iv_count, 0, sizeof(iv_count)); memset(ev_count, 0, sizeof(ev_count)); memset(inner_score, 0, sizeof(inner_score)); memset(inter_score, 0, sizeof(inter_score));
// 计算行内分数 for (int mask = 0; mask < tot; mask++) { int mask_tmp = mask; for (int i = 0; i < n; i++) { int x = mask_tmp % 3; mask_bits[mask][i] = x; mask_tmp /= 3; if (x == 1) { iv_count[mask]++; inner_score[mask] += 120; } elseif (x == 2) { ev_count[mask]++; inner_score[mask] += 40; } if (i > 0) { inner_score[mask] += score[x][mask_bits[mask][i - 1]]; } } } // 计算行间分数 for (int i = 0; i < tot; i++) { for (int j = 0; j < tot; j++) { inter_score[i][j] = 0; for (int k = 0; k < n; k++) { inter_score[i][j] += score[mask_bits[i][k]][mask_bits[j][k]]; } } } }
intgetMaxGridHappiness(int m, int n, int introvertsCount, int extrovertsCount) { int tot = pow(3, n); init_data(m, n, tot); // 记忆化搜索数组,初始化为 -1,表示未赋值 memset(d, -1, sizeof(d)); return dfs(0, 0, introvertsCount, extrovertsCount, m, tot); }
functiongetMaxGridHappiness(m, n, introvertsCount, extrovertsCount) { let tot = Math.pow(3, n); let maskBits = newArray(T).fill(0).map(() =>newArray(N).fill(0)); let ivCount = newArray(T).fill(0); let evCount = newArray(T).fill(0); let innerScore = newArray(T).fill(0); let interScore = newArray(T).fill(0).map(() =>newArray(T).fill(0)); let d = newArray(N).fill(0).map(() =>newArray(T).fill(0).map(() =>newArray(M + 1).fill(0).map(() =>newArray(M + 1).fill(-1))));
initData();
for (let i = 0; i < N; i++) { for (let j = 0; j < T; j++) { for (let k = 0; k <= M; k++) { d[i][j][k].fill(-1); } } }
tot = 3**n mask_bits = [[0] * N for _ inrange(T)] iv_count, ev_count = [0] * T, [0] * T inner_score = [0] * T inter_score = [[0] * T for _ inrange(T)] definit_data() -> None: # 计算行内分数 for mask inrange(tot): mask_tmp = mask for i inrange(n): x = mask_tmp % 3 mask_bits[mask][i] = x mask_tmp //= 3 if x == 1: iv_count[mask] += 1 inner_score[mask] += 120 elif x == 2: ev_count[mask] += 1 inner_score[mask] += 40 if i > 0: inner_score[mask] += score[x][mask_bits[mask][i - 1]] # 计算行间分数 for i inrange(tot): for j inrange(tot): for k inrange(n): inter_score[i][j] += score[mask_bits[i][k]][mask_bits[j][k]] @cache defdfs(row: int, premask: int, iv: int, ev: int) -> int: if row == m or (iv == 0and ev == 0): return0 res = 0 for mask inrange(tot): # mask 包含的内向人数不能超过 iv ,外向人数不能超过 ev if iv_count[mask] > iv or ev_count[mask] > ev: continue res = max(res, dfs(row + 1, mask, iv - iv_count[mask], ev - ev_count[mask]) + inner_score[mask] + inter_score[premask][mask]) return res
public: intgetMaxGridHappiness(int m, int n, int introvertsCount, int extrovertsCount){ this->n = n; this->m = m; // 状态总数为 3^n this->tot = pow(3, n); p[0] = 1; for (int i = 1; i < n; i++) { p[i] = p[i - 1] * 3; } // 记忆化搜索数组,初始化为 -1,表示未赋值 memset(d, -1, sizeof d); returndfs(0, 0, introvertsCount, extrovertsCount); }
intdfs(int pos, int mask, int iv, int ev){ if (pos == n * m || (iv == 0 && ev == 0)) { return0; } int& res = d[pos][mask][iv][ev]; if (res != -1) { return res; } res = 0; int up = mask / p[n - 1], left = mask % 3; // 若处于第一列,则左侧没有元素,将 left 置为 0 if (pos % n == 0) { left = 0; } for (int i = 0; i < 3; i++) { if ((i == 1 && iv == 0) || (i == 2 && ev == 0)) { continue; } int next_mask = mask % p[n - 1] * 3 + i; int score_sum = dfs(pos + 1, next_mask, iv - (i == 1), ev - (i == 2)) + score[up][i] + score[left][i]; if (i == 1) { score_sum += 120; } elseif (i == 2) { score_sum += 40; } res = max(res, score_sum); } return res; } };
publicclassSolution { constint T = 243, N = 5, M = 6; int n, m, tot; int[] p; int[][][][] d; // 邻居间的分数 staticint[][] score = { newint[]{0, 0, 0}, newint[]{0, -60, -10}, newint[]{0, -10, 40} };
publicintGetMaxGridHappiness(int m, int n, int introvertsCount, int extrovertsCount) { this.n = n; this.m = m; // 状态总数为 3^n this.tot = (int) Math.Pow(3, n); this.p = newint[N]; p[0] = 1; for (int i = 1; i < n; i++) { p[i] = p[i - 1] * 3; } this.d = newint[N * N][][][];
// 记忆化搜索数组,初始化为 -1,表示未赋值 for (int i = 0; i < N * N; i++) { d[i] = newint[T][][]; for (int j = 0; j < T; j++) { d[i][j] = newint[M + 1][]; for (int k = 0; k <= M; k++) { d[i][j][k] = newint[M + 1]; Array.Fill(d[i][j][k], -1); } } } return DFS(0, 0, introvertsCount, extrovertsCount); }
publicintDFS(int pos, int mask, int iv, int ev) { if (pos == n * m || (iv == 0 && ev == 0)) { return0; } int res = d[pos][mask][iv][ev]; if (res != -1) { return res; } res = 0; int up = mask / p[n - 1], left = mask % 3; // 若处于第一列,则左侧没有元素,将 left 置为 0 if (pos % n == 0) { left = 0; } for (int i = 0; i < 3; i++) { if ((i == 1 && iv == 0) || (i == 2 && ev == 0)) { continue; } int nextMask = mask % p[n - 1] * 3 + i; int scoreSum = DFS(pos + 1, nextMask, iv - (i == 1 ? 1 : 0), ev - (i == 2 ? 1 : 0)) + score[up][i] + score[left][i]; if (i == 1) { scoreSum += 120; } elseif (i == 2) { scoreSum += 40; } res = Math.Max(res, scoreSum); } d[pos][mask][iv][ev] = res; return res; } }
intdfs(int pos, int mask, int iv, int ev, int m, int n) { if (pos == n * m || (iv == 0 && ev == 0)) { return0; } int* res = &d[pos][mask][iv][ev]; if (*res != -1) { return *res; } *res = 0; int up = mask / p[n - 1], left = mask % 3; // 若处于第一列,则左侧没有元素,将 left 置为 0 if (pos % n == 0) { left = 0; } for (int i = 0; i < 3; i++) { if ((i == 1 && iv == 0) || (i == 2 && ev == 0)) { continue; } int next_mask = mask % p[n - 1] * 3 + i; int score_sum = dfs(pos + 1, next_mask, iv - (i == 1), ev - (i == 2), m, n) + score[up][i] + score[left][i]; if (i == 1) { score_sum += 120; } elseif (i == 2) { score_sum += 40; } *res = fmax(*res, score_sum); } return *res; }
intgetMaxGridHappiness(int m, int n, int introvertsCount, int extrovertsCount){ p[0] = 1; for (int i = 1; i < n; i++) { p[i] = p[i - 1] * 3; } // 记忆化搜索数组,初始化为 -1,表示未赋值 memset(d, -1, sizeof d); return dfs(0, 0, introvertsCount, extrovertsCount, m, n); }
functiongetMaxGridHappiness(m, n, introvertsCount, extrovertsCount) { let tot = Math.pow(3, n); let p = newArray(N).fill(0); p[0] = 1; for (let i = 1; i < n; i++) { p[i] = p[i - 1] * 3; } let d = newArray(N * N).fill(0).map(() =>newArray(T).fill(0).map(() =>newArray(M + 1).fill(0).map(() =>newArray(M + 1).fill(-1))));
for (let i = 0; i < N * N; i++) { for (let j = 0; j < T; j++) { for (let k = 0; k <= M; k++) { d[i][j][k].fill(-1); } } }
tot = 3**n p = [1] for i inrange(1, n): p.append(p[-1] * 3) @cache defdfs(pos: int, mask: int, iv: int, ev: int) -> int: if pos == n * m or (iv == 0and ev == 0): return0 res = 0 up, left = mask // p[n - 1], mask % 3 if pos % n == 0: left = 0 for i inrange(3): if (i == 1and iv == 0) or (i == 2and ev == 0): continue next_mask = mask % p[n - 1] * 3 + i score_sum = dfs(pos + 1, next_mask, iv - (i == 1), ev - (i == 2)) + score[up][i] + score[left][i] if i == 1: score_sum += 120 elif i == 2: score_sum += 40 res = max(res, score_sum)