【每日一题Day246】LC1659最大化网格幸福感 | 状压dp

简介: 【每日一题Day246】LC1659最大化网格幸福感 | 状压dp

*最大化网格幸福感【LC1659】

给你四个整数 mnintrovertsCountextrovertsCount 。有一个 m x n 网格,和两种类型的人:内向的人和外向的人。总共有 introvertsCount 个内向的人和 extrovertsCount 个外向的人。

请你决定网格中应当居住多少人,并为每个人分配一个网格单元。 注意,不必 让所有人都生活在网格中。

每个人的 幸福感 计算如下:

  • 内向的人 开始 时有 120 个幸福感,但每存在一个邻居(内向的或外向的)他都会 失去30 个幸福感。
  • 外向的人 开始 时有 40 个幸福感,每存在一个邻居(内向的或外向的)他都会 得到20 个幸福感。

邻居是指居住在一个人所在单元的上、下、左、右四个直接相邻的单元中的其他人。

网格幸福感 是每个人幸福感的 总和 。 返回 最大可能的网格幸福感

好难 了解一下

状压dp+按行

思路

朴素的dfs会超时,由于每个位置只有「空」「内向」「外向」三种状态,因此可以将这三个状态分别编码为 0,1,2,并用一个长度(位数)为 n 的三进制数对一行的状态进行编码,用状压dp解决。

子问题:如果按行处理的话,枚举每一行的状态得到的最大分数,每一行的分数分为「行内分数」和「行外分数」

  • 「行内分数」:在同一行内每个人的分数,内向 120分,外向 40分;以及由于两人相邻(在同一行内,即左右相邻)贡献的额外分数,两个内向 −60分,两个外向 40 分,其余情况 −10分;

「行外分数」:由于两人相邻(在不同行内,即上下相邻)贡献的额外分数,同理为 −60,40,−10分中的一种

  • 递归的过程中有四个变量:当前选择的行、前一行的状态码、可供选择的内向的人和外向的人的个数,因此在记忆化需要用四维memo记录

image.png

class Solution {
    private int m;
    private int mx;
    private int[] f;
    private int[][] g;// 记录每个位置的消息
    private int[][] bits;
    private int[] ix;
    private int[] ex;
    private Integer[][][][] memo;
    private final int[][] h = {{0, 0, 0}, {0, -60, -10}, {0, -10, 40}};
    public int getMaxGridHappiness(int m, int n, int introvertsCount, int extrovertsCount) {
        this.m = m;
        mx = (int) Math.pow(3, n);// 三进制枚举的最大值
        f = new int[mx];// 行内分数
        g = new int[mx][mx];// 行间分数
        bits = new int[mx][n];// mask中第i列的比特值
        ix = new int[mx];// mask中内向人的个数
        ex = new int[mx];// mask中外向人的个数
        memo = new Integer[m][mx][introvertsCount + 1][extrovertsCount + 1];
        for (int i = 0; i < mx; ++i) {
            int mask = i;
            for (int j = 0; j < n; ++j) {
                int x = mask % 3;// 状态值
                mask /= 3;
                bits[i][j] = x;
                if (x == 1) {
                    ix[i]++;
                    f[i] += 120;
                } else if (x == 2) {
                    ex[i]++;
                    f[i] += 40;
                }
                if (j > 0) {
                    f[i] += h[x][bits[i][j - 1]];
                }
            }
        }
        for (int i = 0; i < mx; ++i) {
            for (int j = 0; j < mx; ++j) {
                for (int k = 0; k < n; ++k) {
                    g[i][j] += h[bits[i][k]][bits[j][k]];
                }
            }
        }
        return dfs(0, 0, introvertsCount, extrovertsCount);
    }
    private int dfs(int i, int pre, int ic, int ec) {
        if (i == m || (ic == 0 && ec == 0)) {
            return 0;
        }
        if (memo[i][pre][ic][ec] != null) {
            return memo[i][pre][ic][ec];
        }
        int ans = 0;
        for (int cur = 0; cur < mx; ++cur) {
            if (ix[cur] <= ic && ex[cur] <= ec) {
                ans = Math.max(ans, f[cur] + g[pre][cur] + dfs(i + 1, cur, ic - ix[cur], ec - ex[cur]));
            }
        }
        return memo[i][pre][ic][ec] = ans;
    }
}
作者:ylb
链接:https://leetcode.cn/problems/maximize-grid-happiness/solutions/2318399/python3javacgotypescript-yi-ti-shuang-ji-fssp/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

轮廓线dp

https://leetcode.cn/problems/maximize-grid-happiness/solutions/2318399/python3javacgotypescript-yi-ti-shuang-ji-fssp/

目录
相关文章
|
6月前
【每日一题Day312】LC2240买钢笔和铅笔的方案数 | 完全背包 数学
【每日一题Day312】LC2240买钢笔和铅笔的方案数 | 完全背包 数学
59 0
|
6月前
|
机器学习/深度学习
【每日一题Day125】LC1326灌溉花园的最少水龙头数目 | 动态规划 贪心
【每日一题Day125】LC1326灌溉花园的最少水龙头数目 | 动态规划 贪心
55 0
|
6月前
|
算法
代码随想录算法训练营第五十七天 | LeetCode 739. 每日温度、496. 下一个更大元素 I
代码随想录算法训练营第五十七天 | LeetCode 739. 每日温度、496. 下一个更大元素 I
47 3
|
6月前
|
存储 算法
代码随想录算法训练营第五十九天 | LeetCode 739. 每日温度、496. 下一个更大元素 I
代码随想录算法训练营第五十九天 | LeetCode 739. 每日温度、496. 下一个更大元素 I
39 1
|
6月前
日拱一卒,月进一步(6)(杨辉三角2)
119. 杨辉三角 II - 力扣(LeetCode)
41 0
|
6月前
【每日一题Day167】LC1000合并石头的最低成本 | 区间dp
【每日一题Day167】LC1000合并石头的最低成本 | 区间dp
55 1
【每日一题Day167】LC1000合并石头的最低成本 | 区间dp
|
机器学习/深度学习
UPC - 2022春混合个人训练赛第五场 D Seahorse Shoes(贪心+模拟)
UPC - 2022春混合个人训练赛第五场 D Seahorse Shoes(贪心+模拟)
85 0
|
6月前
【每日一题Day224】LC2517礼盒的最大甜蜜度 | 二分答案
【每日一题Day224】LC2517礼盒的最大甜蜜度 | 二分答案
32 0
|
6月前
【每日一题Day154】LC1626无矛盾的最佳球队 | 动态规划
【每日一题Day154】LC1626无矛盾的最佳球队 | 动态规划
37 0
|
6月前
|
安全
【每日一题Day137】LC1599经营摩天轮的最大利润 | 模拟+贪心
【每日一题Day137】LC1599经营摩天轮的最大利润 | 模拟+贪心
67 0
下一篇
无影云桌面