• 动态规划-状态压缩-707. 最优账户结余


    2020-04-07 16:52:12

    问题描述:

    给一有向图,每一条边用一个 三元组 表示, 比如 [u, v, w] 代表权值为 w 的从 u 到 v 的一条边. 计算出保证每个点的权重相等需要添加的最少的边数. 也就是说, 指向这一点的边权重总和等于这个点指向其他点的边权重之和.

    样例

    样例1

    输入: [[0,1,10],[2,0,5]]
    输出: 2
    说明:
    需要添加两条边
    它们是 [1,0,5] 以及 [1,2,5]

    样例2

    输入: [[0,1,10],[1,0,1],[1,2,5],[2,0,5]]
    输出: 1
    说明:
    只需要添加一条边 [1,0,4]

    注意事项

    1. 注意 u ≠ v 且 w > 0
    2. 下标不一定是线性的, 比如 顶点下标可以为 0,1,2, 也可以为 0,2,6.

    问题求解:

    本题可以使用动态规划来进行求解,对于一个集合,如何其和为0,那么就是一个合法的子集,我们只需要去遍历其合法的子集组成就可以得到最终的结果。

    时间复杂度:O(2 ^ n)

        public int balanceGraph(int[][] edges) {
            Map<Integer, Integer> map = new HashMap<>();
            for (int[] e : edges) {
                int from = e[0];
                int to = e[1];
                int w = e[2];
                map.put(from, map.getOrDefault(from, 0) - w);
                map.put(to, map.getOrDefault(to, 0) + w);
            }
            int[] nums = new int[map.size()];
            int len = 0;
            for (int v : map.values()) {
                if (v != 0) {
                    nums[len++] = v;
                }
            }
            if (len == 0) return 0;
            int[] dp = new int[1 << len];
            Arrays.fill(dp, Integer.MAX_VALUE / 2);
            for (int i = 1; i < dp.length; i++) {
                int sum = 0;
                int cnt = 0;
                for (int j = 0; j < len; j++) {
                    if ((1 << j & i) != 0) {
                        sum += nums[j];
                        cnt += 1;
                    }
                }
                if (sum == 0) {
                    dp[i] = cnt - 1;
                    for (int j = 1; j < dp.length; j++) {
                        if ((j & i) == j) {
                            dp[i] = Math.min(dp[i], dp[j] + dp[i - j]);
                        }
                    }
                }
            }
            return dp[dp.length - 1];
        }
    

      

  • 相关阅读:
    解决“Kali Linux终端打不开”
    国内网站备案。备案的是域名?还是服务器?
    Linux磁盘分区
    Linux各目录的作用
    vim基础操作
    基础算法-->堆排序
    期望,方差,标准差,正态分布
    平面向量
    基础算法 ---> 二分法
    学习人工智能准备了解的算法
  • 原文地址:https://www.cnblogs.com/hyserendipity/p/12654366.html
Copyright © 2020-2023  润新知