class079 树型dp-下【算法】

简介: class079 树型dp-下【算法】

class079 树型dp-下【算法】

算法讲解079【必备】树型dp-下

code1 2477. 到达首都的最少油耗

// 到达首都的最少油耗

// 给你一棵 n 个节点的树(一个无向、连通、无环图)

// 每个节点表示一个城市,编号从 0 到 n - 1 ,且恰好有 n - 1 条路

// 0 是首都。给你一个二维整数数组 roads

// 其中 roads[i] = [ai, bi] ,表示城市 ai 和 bi 之间有一条 双向路

// 每个城市里有一个代表,他们都要去首都参加一个会议

// 每座城市里有一辆车。给你一个整数 seats 表示每辆车里面座位的数目

// 城市里的代表可以选择乘坐所在城市的车,或者乘坐其他城市的车

// 相邻城市之间一辆车的油耗是一升汽油

// 请你返回到达首都最少需要多少升汽油

// 测试链接 : https://leetcode.cn/problems/minimum-fuel-cost-to-report-to-the-capital/

以x为头

孩子的最少油耗+孩子的人数/seats向上取整

package class079;
import java.util.ArrayList;
// 到达首都的最少油耗
// 给你一棵 n 个节点的树(一个无向、连通、无环图)
// 每个节点表示一个城市,编号从 0 到 n - 1 ,且恰好有 n - 1 条路
// 0 是首都。给你一个二维整数数组 roads
// 其中 roads[i] = [ai, bi] ,表示城市 ai 和 bi 之间有一条 双向路
// 每个城市里有一个代表,他们都要去首都参加一个会议
// 每座城市里有一辆车。给你一个整数 seats 表示每辆车里面座位的数目
// 城市里的代表可以选择乘坐所在城市的车,或者乘坐其他城市的车
// 相邻城市之间一辆车的油耗是一升汽油
// 请你返回到达首都最少需要多少升汽油
// 测试链接 : https://leetcode.cn/problems/minimum-fuel-cost-to-report-to-the-capital/
public class Code01_MinimumFuelCost {
  public static long minimumFuelCost(int[][] roads, int seats) {
    int n = roads.length + 1;
    ArrayList<ArrayList<Integer>> graph = new ArrayList<>();
    for (int i = 0; i < n; i++) {
      graph.add(new ArrayList<>());
    }
    for (int[] r : roads) {
      graph.get(r[0]).add(r[1]);
      graph.get(r[1]).add(r[0]);
    }
    int[] size = new int[n];
    long[] cost = new long[n];
    f(graph, seats, 0, -1, size, cost);
    return cost[0];
  }
  // 根据图,当前来到u,u的父节点是p
  // 遍历完成后,请填好size[u]、cost[u]
  public static void f(ArrayList<ArrayList<Integer>> graph, int seats, int u, int p, int[] size, long[] cost) {
    size[u] = 1;
    for (int v : graph.get(u)) {
      if (v != p) {
        f(graph, seats, v, u, size, cost);
        size[u] += size[v];
        cost[u] += cost[v];
        // a/b向上取整,可以写成(a+b-1)/b
        // (size[v]+seats-1) / seats = size[v] / seats 向上取整
        cost[u] += (size[v] + seats - 1) / seats;
      }
    }
  }
}

code2 2246. 相邻字符不同的最长路径

// 相邻字符不同的最长路径

// 给你一棵 树(即一个连通、无向、无环图),根节点是节点 0

// 这棵树由编号从 0 到 n - 1 的 n 个节点组成

// 用下标从 0 开始、长度为 n 的数组 parent 来表示这棵树

// 其中 parent[i] 是节点 i 的父节点

// 由于节点 0 是根节点,所以 parent[0] == -1

// 另给你一个字符串 s ,长度也是 n ,其中 s[i] 表示分配给节点 i 的字符

// 请你找出路径上任意一对相邻节点都没有分配到相同字符的 最长路径

// 并返回该路径的长度

// 测试链接 : https://leetcode.cn/problems/longest-path-with-different-adjacent-characters/

以x为头的树

不要x:孩子的最长路径的最大值

要x:和x不同的耗子的最长路径+次长路径

返回[包含头结点的最长路径,最长路径]

叶子结点返回(1,1)

package class079;
import java.util.ArrayList;
// 相邻字符不同的最长路径
// 给你一棵 树(即一个连通、无向、无环图),根节点是节点 0
// 这棵树由编号从 0 到 n - 1 的 n 个节点组成
// 用下标从 0 开始、长度为 n 的数组 parent 来表示这棵树
// 其中 parent[i] 是节点 i 的父节点
// 由于节点 0 是根节点,所以 parent[0] == -1
// 另给你一个字符串 s ,长度也是 n ,其中 s[i] 表示分配给节点 i 的字符
// 请你找出路径上任意一对相邻节点都没有分配到相同字符的 最长路径
// 并返回该路径的长度
// 测试链接 : https://leetcode.cn/problems/longest-path-with-different-adjacent-characters/
public class Code02_LongestPathWithDifferentAdjacent {
  public static int longestPath(int[] parent, String str) {
    int n = parent.length;
    char[] s = str.toCharArray();
    ArrayList<ArrayList<Integer>> graph = new ArrayList<>();
    for (int i = 0; i < n; i++) {
      graph.add(new ArrayList<>());
    }
    for (int i = 1; i < n; i++) {
      graph.get(parent[i]).add(i);
    }
    return f(s, graph, 0).maxPath;
  }
  public static class Info {
    public int maxPathFromHead; // 一定要从头节点出发的情况下,相邻字符不等的最长路径长度
    public int maxPath; // 整棵树上,相邻字符不等的最长路径长度
    public Info(int a, int b) {
      maxPathFromHead = a;
      maxPath = b;
    }
  }
  public static Info f(char[] s, ArrayList<ArrayList<Integer>> graph, int u) {
    if (graph.get(u).isEmpty()) {
      // u节点是叶
      return new Info(1, 1);
    }
    int max1 = 0; // 下方最长链
    int max2 = 0; // 下方次长链
    int maxPath = 1;
    for (int v : graph.get(u)) {
      Info nextInfo = f(s, graph, v);
      maxPath = Math.max(maxPath, nextInfo.maxPath);
      if (s[u] != s[v]) {
        if (nextInfo.maxPathFromHead > max1) {
          max2 = max1;
          max1 = nextInfo.maxPathFromHead;
        } else if (nextInfo.maxPathFromHead > max2) {
          max2 = nextInfo.maxPathFromHead;
        }
      }
    }
    int maxPathFromHead = max1 + 1;
    maxPath = Math.max(maxPath, max1 + max2 + 1);
    return new Info(maxPathFromHead, maxPath);
  }
}

code3 2458. 移除子树后的二叉树高度

// 移除子树后的二叉树高度

// 给你一棵 二叉树 的根节点 root ,树中有 n 个节点

// 每个节点都可以被分配一个从 1 到 n 且互不相同的值

// 另给你一个长度为 m 的数组 queries

// 你必须在树上执行 m 个 独立 的查询,其中第 i 个查询你需要执行以下操作:

// 从树中 移除 以 queries[i] 的值作为根节点的子树

// 题目所用测试用例保证 queries[i] 不等于根节点的值

// 返回一个长度为 m 的数组 answer

// 其中 answer[i] 是执行第 i 个查询后树的高度

// 注意:

// 查询之间是独立的,所以在每个查询执行后,树会回到其初始状态

// 树的高度是从根到树中某个节点的 最长简单路径中的边数

// 测试链接 : https://leetcode.cn/problems/height-of-binary-tree-after-subtree-removal-queries/

dfn序号+size

每一个结点的深度

package class079;
// 移除子树后的二叉树高度
// 给你一棵 二叉树 的根节点 root ,树中有 n 个节点
// 每个节点都可以被分配一个从 1 到 n 且互不相同的值
// 另给你一个长度为 m 的数组 queries
// 你必须在树上执行 m 个 独立 的查询,其中第 i 个查询你需要执行以下操作:
// 从树中 移除 以 queries[i] 的值作为根节点的子树
// 题目所用测试用例保证 queries[i] 不等于根节点的值
// 返回一个长度为 m 的数组 answer
// 其中 answer[i] 是执行第 i 个查询后树的高度
// 注意:
// 查询之间是独立的,所以在每个查询执行后,树会回到其初始状态
// 树的高度是从根到树中某个节点的 最长简单路径中的边数
// 测试链接 : https://leetcode.cn/problems/height-of-binary-tree-after-subtree-removal-queries/
public class Code03_HeightRemovalQueries {
  // 不要提交这个类
  public static class TreeNode {
    public int val;
    public TreeNode left;
    public TreeNode right;
  }
  // 提交如下的方法
  public static final int MAXN = 100010;
  // 下标为节点的值
  public static int[] dfn = new int[MAXN];
  // 下标为dfn序号
  public static int[] deep = new int[MAXN];
  // 下标为dfn序号
  public static int[] size = new int[MAXN];
  public static int[] maxl = new int[MAXN];
  public static int[] maxr = new int[MAXN];
  public static int dfnCnt;
  public static int[] treeQueries(TreeNode root, int[] queries) {
    dfnCnt = 0;
    f(root, 0);
    for (int i = 1; i <= dfnCnt; i++) {
      maxl[i] = Math.max(maxl[i - 1], deep[i]);
    }
    maxr[dfnCnt + 1] = 0;
    for (int i = dfnCnt; i >= 1; i--) {
      maxr[i] = Math.max(maxr[i + 1], deep[i]);
    }
    int m = queries.length;
    int[] ans = new int[m];
    for (int i = 0; i < m; i++) {
      int leftMax = maxl[dfn[queries[i]] - 1];
      int rightMax = maxr[dfn[queries[i]] + size[dfn[queries[i]]]];
      ans[i] = Math.max(leftMax, rightMax);
    }
    return ans;
  }
  // 来到x节点,从头节点到x节点经过了k条边
  public static void f(TreeNode x, int k) {
    int i = ++dfnCnt;
    dfn[x.val] = i;
    deep[i] = k;
    size[i] = 1;
    if (x.left != null) {
      f(x.left, k + 1);
      size[i] += size[dfn[x.left.val]];
    }
    if (x.right != null) {
      f(x.right, k + 1);
      size[i] += size[dfn[x.right.val]];
    }
  }
}

code4 2322. 从树中删除边的最小分数

// 从树中删除边的最小分数

// 存在一棵无向连通树,树中有编号从0到n-1的n个节点,以及n-1条边

// 给你一个下标从0开始的整数数组nums长度为n,其中nums[i]表示第i个节点的值

// 另给你一个二维整数数组edges长度为n-1

// 其中 edges[i] = [ai, bi] 表示树中存在一条位于节点 ai 和 bi 之间的边

// 删除树中两条不同的边以形成三个连通组件,对于一种删除边方案,定义如下步骤以计算其分数:

// 分别获取三个组件每个组件中所有节点值的异或值

// 最大 异或值和 最小 异或值的 差值 就是这种删除边方案的分数

// 返回可能的最小分数

// 测试链接 : https://leetcode.cn/problems/minimum-score-after-removals-on-a-tree/

暴力枚举两条边

如果x,y

y>x,y是x的子树

sum1=sumY

sum2=sumX^sumY

sum3=sum0^sumX

y>x,y不是x的子树

sum1=sumY

sum2=sumX

sum3=sum0^ sumX^sumY

package class079;
import java.util.ArrayList;
import java.util.Arrays;
// 从树中删除边的最小分数
// 存在一棵无向连通树,树中有编号从0到n-1的n个节点,以及n-1条边
// 给你一个下标从0开始的整数数组nums长度为n,其中nums[i]表示第i个节点的值
// 另给你一个二维整数数组edges长度为n-1
// 其中 edges[i] = [ai, bi] 表示树中存在一条位于节点 ai 和 bi 之间的边
// 删除树中两条不同的边以形成三个连通组件,对于一种删除边方案,定义如下步骤以计算其分数:
// 分别获取三个组件每个组件中所有节点值的异或值
// 最大 异或值和 最小 异或值的 差值 就是这种删除边方案的分数
// 返回可能的最小分数
// 测试链接 : https://leetcode.cn/problems/minimum-score-after-removals-on-a-tree/
public class Code04_MinimumScoreAfterRemovals {
  public static int MAXN = 1001;
  // 下标为原始节点编号
  public static int[] dfn = new int[MAXN];
  // 下标为dfn序号
  public static int[] xor = new int[MAXN];
  // 下标为dfn序号
  public static int[] size = new int[MAXN];
  public static int dfnCnt;
  public static int minimumScore(int[] nums, int[][] edges) {
    int n = nums.length;
    ArrayList<ArrayList<Integer>> graph = new ArrayList<>();
    for (int i = 0; i < n; i++) {
      graph.add(new ArrayList<>());
    }
    for (int[] edge : edges) {
      graph.get(edge[0]).add(edge[1]);
      graph.get(edge[1]).add(edge[0]);
    }
    Arrays.fill(dfn, 0, n, 0);
    dfnCnt = 0;
    f(nums, graph, 0);
    int m = edges.length;
    int ans = Integer.MAX_VALUE;
    for (int i = 0, a, b, pre, pos, sum1, sum2, sum3; i < m; i++) {
      a = Math.max(dfn[edges[i][0]], dfn[edges[i][1]]);
      for (int j = i + 1; j < m; j++) {
        b = Math.max(dfn[edges[j][0]], dfn[edges[j][1]]);
        if (a < b) {
          pre = a;
          pos = b;
        } else {
          pre = b;
          pos = a;
        }
        sum1 = xor[pos];
        // xor[1] : 整棵树的异或和
        // 因为头节点是0,一定拥有最小的dfn序号1
        // f函数调用的时候,也是从0节点开始的
        if (pos < pre + size[pre]) {
          sum2 = xor[pre] ^ xor[pos];
          sum3 = xor[1] ^ xor[pre];
        } else {
          sum2 = xor[pre];
          sum3 = xor[1] ^ sum1 ^ sum2;
        }
        ans = Math.min(ans, Math.max(Math.max(sum1, sum2), sum3) - Math.min(Math.min(sum1, sum2), sum3));
      }
    }
    return ans;
  }
  // 当前来到原始编号u,遍历u的整棵树
  public static void f(int[] nums, ArrayList<ArrayList<Integer>> graph, int u) {
    int i = ++dfnCnt;
    dfn[u] = i;
    xor[i] = nums[u];
    size[i] = 1;
    for (int v : graph.get(u)) {
      if (dfn[v] == 0) {
        f(nums, graph, v);
        xor[i] ^= xor[dfn[v]];
        size[i] += size[dfn[v]];
      }
    }
  }
}

code5 P2014 [CTSC1997] 选课

// 选课

// 在大学里每个学生,为了达到一定的学分,必须从很多课程里选择一些课程来学习

// 在课程里有些课程必须在某些课程之前学习,如高等数学总是在其它课程之前学习

// 现在有 N 门功课,每门课有个学分,每门课有一门或没有直接先修课

// 若课程 a 是课程 b 的先修课即只有学完了课程 a,才能学习课程 b

// 一个学生要从这些课程里选择 M 门课程学习

// 问他能获得的最大学分是多少

// 测试链接 : https://www.luogu.com.cn/problem/P2014

// 请同学们务必参考如下代码中关于输入、输出的处理

// 这是输入输出处理效率很高的写法

// 提交以下的code,提交时请把类名改成"Main",可以直接通过

方法1

当前来到i号节点为头的子树

只在i号节点、及其i号节点下方的前j棵子树上挑选节点

一共挑选k个节点,并且保证挑选的节点连成一片

返回最大的累加和

public static int f(int i, int j, int k)

f(i,j-1,k)

以i最后第一个孩子枚举s,1<=s<k

f(i,j-1,k-s)+f(v,v.size,s)

方法2

dp[i][j] : i ~ n+1 范围的节点,选择j个节点一定要形成有效结构的情况下,最大的累加和

不选i及其子树

学i结点

dp[i][j] = Math.max(dp[i + size[i]][j], val[i] + dp[i + 1][j - 1]);

package class079;
// 选课
// 在大学里每个学生,为了达到一定的学分,必须从很多课程里选择一些课程来学习
// 在课程里有些课程必须在某些课程之前学习,如高等数学总是在其它课程之前学习
// 现在有 N 门功课,每门课有个学分,每门课有一门或没有直接先修课
// 若课程 a 是课程 b 的先修课即只有学完了课程 a,才能学习课程 b
// 一个学生要从这些课程里选择 M 门课程学习
// 问他能获得的最大学分是多少
// 测试链接 : https://www.luogu.com.cn/problem/P2014
// 请同学们务必参考如下代码中关于输入、输出的处理
// 这是输入输出处理效率很高的写法
// 提交以下的code,提交时请把类名改成"Main",可以直接通过
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.ArrayList;
// 普通解法,邻接表建图 + 相对好懂的动态规划
// 几乎所有题解都是普通解法的思路,只不过优化了常数时间、做了空间压缩
// 但时间复杂度依然是O(n * 每个节点的孩子平均数量 * m的平方)
public class Code05_CourseSelection1 {
  public static int MAXN = 301;
  public static int[] nums = new int[MAXN];
  public static ArrayList<ArrayList<Integer>> graph;
  static {
    graph = new ArrayList<>();
    for (int i = 0; i < MAXN; i++) {
      graph.add(new ArrayList<>());
    }
  }
  public static int[][][] dp = new int[MAXN][][];
  public static int n, m;
  public static void build(int n) {
    for (int i = 0; i <= n; i++) {
      graph.get(i).clear();
    }
  }
  public static void main(String[] args) throws IOException {
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    StreamTokenizer in = new StreamTokenizer(br);
    PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
    while (in.nextToken() != StreamTokenizer.TT_EOF) {
      // 节点编号从0~n
      n = (int) in.nval;
      in.nextToken();
      m = (int) in.nval + 1;
      build(n);
      for (int i = 1, pre; i <= n; i++) {
        in.nextToken();
        pre = (int) in.nval;
        graph.get(pre).add(i);
        in.nextToken();
        nums[i] = (int) in.nval;
      }
      out.println(compute());
    }
    out.flush();
    out.close();
    br.close();
  }
  public static int compute() {
    for (int i = 0; i <= n; i++) {
      dp[i] = new int[graph.get(i).size() + 1][m + 1];
    }
    for (int i = 0; i <= n; i++) {
      for (int j = 0; j < dp[i].length; j++) {
        for (int k = 0; k <= m; k++) {
          dp[i][j][k] = -1;
        }
      }
    }
    return f(0, graph.get(0).size(), m);
  }
  // 当前来到i号节点为头的子树
  // 只在i号节点、及其i号节点下方的前j棵子树上挑选节点
  // 一共挑选k个节点,并且保证挑选的节点连成一片
  // 返回最大的累加和
  public static int f(int i, int j, int k) {
    if (k == 0) {
      return 0;
    }
    if (j == 0 || k == 1) {
      return nums[i];
    }
    if (dp[i][j][k] != -1) {
      return dp[i][j][k];
    }
    int ans = f(i, j - 1, k);
    // 第j棵子树头节点v 
    int v = graph.get(i).get(j - 1);
    for (int s = 1; s < k; s++) {
      ans = Math.max(ans, f(i, j - 1, k - s) + f(v, graph.get(v).size(), s));
    }
    dp[i][j][k] = ans;
    return ans;
  }
}
package class079;
// 选课
// 在大学里每个学生,为了达到一定的学分,必须从很多课程里选择一些课程来学习
// 在课程里有些课程必须在某些课程之前学习,如高等数学总是在其它课程之前学习
// 现在有 N 门功课,每门课有个学分,每门课有一门或没有直接先修课
// 若课程 a 是课程 b 的先修课即只有学完了课程 a,才能学习课程 b
// 一个学生要从这些课程里选择 M 门课程学习
// 问他能获得的最大学分是多少
// 测试链接 : https://www.luogu.com.cn/problem/P2014
// 请同学们务必参考如下代码中关于输入、输出的处理
// 这是输入输出处理效率很高的写法
// 提交以下的code,提交时请把类名改成"Main",可以直接通过
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.Arrays;
// 最优解,链式前向星建图 + dfn序的利用 + 巧妙定义下的尝试
// 时间复杂度O(n*m),觉得难可以跳过,这个最优解是非常巧妙和精彩的!
public class Code05_CourseSelection2 {
  public static int MAXN = 301;
  public static int[] nums = new int[MAXN];
  // 链式前向星建图
  public static int edgeCnt;
  public static int[] head = new int[MAXN];
  public static int[] next = new int[MAXN];
  public static int[] to = new int[MAXN];
  // dfn的计数
  public static int dfnCnt;
  // 下标为dfn序号
  public static int[] val = new int[MAXN + 1];
  // 下标为dfn序号
  public static int[] size = new int[MAXN + 1];
  // 动态规划表
  public static int[][] dp = new int[MAXN + 2][MAXN];
  public static int n, m;
  public static void build(int n, int m) {
    edgeCnt = 1;
    dfnCnt = 0;
    Arrays.fill(head, 0, n + 1, 0);
    Arrays.fill(dp[n + 2], 0, m + 1, 0);
  }
  public static void addEdge(int u, int v) {
    next[edgeCnt] = head[u];
    to[edgeCnt] = v;
    head[u] = edgeCnt++;
  }
  public static void main(String[] args) throws IOException {
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    StreamTokenizer in = new StreamTokenizer(br);
    PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
    while (in.nextToken() != StreamTokenizer.TT_EOF) {
      n = (int) in.nval;
      in.nextToken();
      m = (int) in.nval;
      build(n, m);
      for (int i = 1; i <= n; i++) {
        in.nextToken();
        addEdge((int) in.nval, i);
        in.nextToken();
        nums[i] = (int) in.nval;
      }
      out.println(compute());
    }
    out.flush();
    out.close();
    br.close();
  }
  public static int compute() {
    f(0);
    // 节点编号0 ~ n,dfn序号范围1 ~ n+1
    // 接下来的逻辑其实就是01背包!不过经历了很多转化
    // 整体的顺序是根据dfn序来进行的,从大的dfn序,遍历到小的dfn序
    // dp[i][j] : i ~ n+1 范围的节点,选择j个节点一定要形成有效结构的情况下,最大的累加和
    // 怎么定义有效结构?重点!重点!重点!
    // 假设i ~ n+1范围上,目前所有头节点的上方,有一个总的头节点
    // i ~ n+1范围所有节点,选出来j个节点的结构,
    // 挂在这个假想的总头节点之下,是一个连续的结构,没有断开的情况
    // 那么就说,i ~ n+1范围所有节点,选出来j个节点的结构是一个有效结构
    for (int i = n + 1; i >= 2; i--) {
      for (int j = 1; j <= m; j++) {
        dp[i][j] = Math.max(dp[i + size[i]][j], val[i] + dp[i + 1][j - 1]);
      }
    }
    // dp[2][m] : 2 ~ n范围上,选择m个节点一定要形成有效结构的情况下,最大的累加和
    // 最后来到dfn序为1的节点,一定是原始的0号节点
    // 原始0号节点下方一定挂着有效结构
    // 并且和补充的0号节点一定能整体连在一起,没有任何跳跃连接
    // 于是整个问题解决
    return nums[0] + dp[2][m];
  }
  // u这棵子树的节点数返回
  public static int f(int u) {
    int i = ++dfnCnt;
    val[i] = nums[u];
    size[i] = 1;
    for (int ei = head[u], v; ei > 0; ei = next[ei]) {
      v = to[ei];
      size[i] += f(v);
    }
    return size[i];
  }
}

2023-11-26 20:48:06

相关文章
|
27天前
|
机器学习/深度学习 算法 搜索推荐
Machine Learning机器学习之决策树算法 Decision Tree(附Python代码)
Machine Learning机器学习之决策树算法 Decision Tree(附Python代码)
|
1月前
|
存储 人工智能 算法
图与树的遍历:探索广度优先、深度优先及其他遍历算法的原理与实现
图与树的遍历:探索广度优先、深度优先及其他遍历算法的原理与实现
63 0
|
1天前
|
机器学习/深度学习 算法 搜索推荐
R语言LASSO特征选择、决策树CART算法和CHAID算法电商网站购物行为预测分析
R语言LASSO特征选择、决策树CART算法和CHAID算法电商网站购物行为预测分析
|
2天前
|
机器学习/深度学习 数据采集 算法
Python用逻辑回归、决策树、SVM、XGBoost 算法机器学习预测用户信贷行为数据分析报告
Python用逻辑回归、决策树、SVM、XGBoost 算法机器学习预测用户信贷行为数据分析报告
|
4天前
|
算法
数据结构与算法-AVL树入门
数据结构与算法-AVL树入门
8 0
|
4天前
|
算法
数据结构与算法-Trie树添加与搜索
数据结构与算法-Trie树添加与搜索
5 0
|
4天前
|
机器学习/深度学习 数据采集 算法
共享单车需求量数据用CART决策树、随机森林以及XGBOOST算法登记分类及影响因素分析
共享单车需求量数据用CART决策树、随机森林以及XGBOOST算法登记分类及影响因素分析
11 0
|
6天前
|
机器学习/深度学习 算法 数据挖掘
数据分享|R语言逻辑回归、Naive Bayes贝叶斯、决策树、随机森林算法预测心脏病
数据分享|R语言逻辑回归、Naive Bayes贝叶斯、决策树、随机森林算法预测心脏病
20 6
|
6天前
|
机器学习/深度学习 算法 数据挖掘
R语言逻辑回归、Naive Bayes贝叶斯、决策树、随机森林算法预测心脏病
R语言逻辑回归、Naive Bayes贝叶斯、决策树、随机森林算法预测心脏病
|
8天前
|
机器学习/深度学习 算法
R语言逻辑回归、Naive Bayes贝叶斯、决策树、随机森林算法预测心脏病-2
R语言逻辑回归、Naive Bayes贝叶斯、决策树、随机森林算法预测心脏病
24 5