class077 区间dp-下【算法】

class077 区间dp-下【算法】

算法讲解077【必备】区间dp-下

在这里插入图片描述

code1 括号区间匹配

// 完成配对需要的最少字符数量
// 给定一个由’[‘、’]‘、’(‘,’)‘组成的字符串
// 请问最少插入多少个括号就能使这个字符串的所有括号正确配对
// 例如当前串是 “([[])”,那么插入一个’]'即可满足
// 输出最少需要插入多少个字符
// 测试链接 : https://www.nowcoder.com/practice/e391767d80d942d29e6095a935a5b96b
// 请同学们务必参考如下代码中关于输入、输出的处理
// 这是输入输出处理效率很高的写法
// 提交以下的code,提交时请把类名改成"Main",可以直接通过

dp[L][R]
1)L位置和R位置匹配,dp[L+1][R-1]
2)枚举m dp[L][m]+dp[m+1][R]

package class077;// 完成配对需要的最少字符数量
// 给定一个由'['、']'、'(',')'组成的字符串
// 请问最少插入多少个括号就能使这个字符串的所有括号正确配对
// 例如当前串是 "([[])",那么插入一个']'即可满足
// 输出最少需要插入多少个字符
// 测试链接 : https://www.nowcoder.com/practice/e391767d80d942d29e6095a935a5b96b
// 请同学们务必参考如下代码中关于输入、输出的处理
// 这是输入输出处理效率很高的写法
// 提交以下的code,提交时请把类名改成"Main",可以直接通过import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;public class Code01_MinimumInsertionsToMatch {public static void main(String[] args) throws IOException {BufferedReader br = new BufferedReader(new InputStreamReader(System.in));PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));String str = br.readLine();out.println(compute(str));out.flush();out.close();br.close();}// 时间复杂度O(n^3)public static int compute(String str) {char[] s = str.toCharArray();int n = s.length;int[][] dp = new int[n][n];for (int i = 0; i < n; i++) {for (int j = 0; j < n; j++) {dp[i][j] = -1;}}return f(s, 0, s.length - 1, dp);}// 让s[l...r]配对至少需要几个字符public static int f(char[] s, int l, int r, int[][] dp) {if (l == r) {return 1;}if (l == r - 1) {if ((s[l] == '(' && s[r] == ')') || (s[l] == '[' && s[r] == ']')) {return 0;}return 2;}// l...r字符数量 >= 3if (dp[l][r] != -1) {return dp[l][r];}// 可能性1 : [l]、[r]本来就是配对的int p1 = Integer.MAX_VALUE;if ((s[l] == '(' && s[r] == ')') || (s[l] == '[' && s[r] == ']')) {p1 = f(s, l + 1, r - 1, dp);}// 可能性2 : 基于每个可能的划分点,做左右划分int p2 = Integer.MAX_VALUE;for (int m = l; m < r; m++) {p2 = Math.min(p2, f(s, l, m, dp) + f(s, m + 1, r, dp));}int ans = Math.min(p1, p2);dp[l][r] = ans;return ans;}}

code2 664. 奇怪的打印机

// 涂色 & 奇怪打印机
// 假设你有一条长度为5的木板,初始时没有涂过任何颜色
// 你希望把它的5个单位长度分别涂上红、绿、蓝、绿、红
// 用一个长度为5的字符串表示这个目标:RGBGR
// 每次你可以把一段连续的木板涂成一个给定的颜色,后涂的颜色覆盖先涂的颜色
// 例如第一次把木板涂成RRRRR
// 第二次涂成RGGGR
// 第三次涂成RGBGR,达到目标
// 返回尽量少的涂色次数
// 测试链接 : https://www.luogu.com.cn/problem/P4170
// 测试链接 : https://leetcode.cn/problems/strange-printer/
// 请同学们务必参考如下代码中关于输入、输出的处理
// 这是输入输出处理效率很高的写法
// 提交以下的code,提交时请把类名改成"Main",可以直接通过

dp[L][R]:L…R刷出给定的颜色至少涂几次
1)[L]==[R]: dp[L][R-1]或dp[L+1][R]
2)[L]!=[R]:枚举m,dp[L][m]+dp[m+1][R]

package class077;// 涂色 & 奇怪打印机
// 假设你有一条长度为5的木板,初始时没有涂过任何颜色
// 你希望把它的5个单位长度分别涂上红、绿、蓝、绿、红
// 用一个长度为5的字符串表示这个目标:RGBGR
// 每次你可以把一段连续的木板涂成一个给定的颜色,后涂的颜色覆盖先涂的颜色
// 例如第一次把木板涂成RRRRR
// 第二次涂成RGGGR
// 第三次涂成RGBGR,达到目标
// 返回尽量少的涂色次数
// 测试链接 : https://www.luogu.com.cn/problem/P4170
// 测试链接 : https://leetcode.cn/problems/strange-printer/
// 请同学们务必参考如下代码中关于输入、输出的处理
// 这是输入输出处理效率很高的写法
// 提交以下的code,提交时请把类名改成"Main",可以直接通过import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;public class Code02_Coloring {public static void main(String[] args) throws IOException {BufferedReader br = new BufferedReader(new InputStreamReader(System.in));PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));String str = br.readLine();out.println(strangePrinter(str));out.flush();out.close();br.close();}// 时间复杂度O(n^3)// 测试链接 : https://leetcode.cn/problems/strange-printer/public static int strangePrinter(String str) {char[] s = str.toCharArray();int n = s.length;int[][] dp = new int[n][n];dp[n - 1][n - 1] = 1;for (int i = 0; i < n - 1; i++) {dp[i][i] = 1;dp[i][i + 1] = s[i] == s[i + 1] ? 1 : 2;}for (int l = n - 3, ans; l >= 0; l--) {for (int r = l + 2; r < n; r++) {// dp[l][r]if (s[l] == s[r]) {dp[l][r] = dp[l][r - 1];// dp[l][r] = dp[l + 1][r];} else {ans = Integer.MAX_VALUE;for (int m = l; m < r; m++) {ans = Math.min(ans, dp[l][m] + dp[m + 1][r]);}dp[l][r] = ans;}}}return dp[0][n - 1];}}

code3 P3205 [HNOI2010] 合唱队

// 合唱队
// 具体描述情打开链接查看
// 测试链接 : https://www.luogu.com.cn/problem/P3205
// 请同学们务必参考如下代码中关于输入、输出的处理
// 这是输入输出处理效率很高的写法
// 提交以下的所有代码,并把主类名改成"Main",可以直接通过

dp[L][R]
[0]:表示[L]最后插入;[1]:表示[R]最后插入
dp[L][R][0]:以下之和
[L]<[L+1]?dp[L+1][R][0]:0
[L]<[R]?dp[L][R-1][1]:0
dp[L][R][1]:以下之和
[R]>[L+1]?dp[L][R-1][0]:0
[R]>[R-1]?dp[L][R-1][1]:0

返回dp[0][n-1][0]+dp[0][n-1][1]

package class077;// 合唱队
// 具体描述情打开链接查看
// 测试链接 : https://www.luogu.com.cn/problem/P3205
// 请同学们务必参考如下代码中关于输入、输出的处理
// 这是输入输出处理效率很高的写法
// 提交以下的所有代码,并把主类名改成"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;public class Code03_HeightAndChoir {public static int MAXN = 1001;public static int[] nums = new int[MAXN];public static int[][] dp = new int[MAXN][2];public static int n;public static int MOD = 19650827;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;for (int i = 1; i <= n; i++) {in.nextToken();nums[i] = (int) in.nval;}if (n == 1) {out.println(1);} else {out.println(compute2());}}out.flush();out.close();br.close();}// 时间复杂度O(n^2)// 严格位置依赖的动态规划public static int compute1() {// 人的编号范围 : 1...n// dp[l][r][0] : 形成l...r的状况的方法数,同时要求l位置的数字是最后出现的// dp[l][r][1] : 形成l...r的状况的方法数,同时要求r位置的数字是最后出现的int[][][] dp = new int[n + 1][n + 1][2];for (int i = 1; i < n; i++) {if (nums[i] < nums[i + 1]) {dp[i][i + 1][0] = 1;dp[i][i + 1][1] = 1;}}for (int l = n - 2; l >= 1; l--) {for (int r = l + 2; r <= n; r++) {if (nums[l] < nums[l + 1]) {dp[l][r][0] = (dp[l][r][0] + dp[l + 1][r][0]) % MOD;}if (nums[l] < nums[r]) {dp[l][r][0] = (dp[l][r][0] + dp[l + 1][r][1]) % MOD;}if (nums[r] > nums[l]) {dp[l][r][1] = (dp[l][r][1] + dp[l][r - 1][0]) % MOD;}if (nums[r] > nums[r - 1]) {dp[l][r][1] = (dp[l][r][1] + dp[l][r - 1][1]) % MOD;}}}return (dp[1][n][0] + dp[1][n][1]) % MOD;}// 时间复杂度O(n^2)// 空间压缩public static int compute2() {if (nums[n - 1] < nums[n]) {dp[n][0] = 1;dp[n][1] = 1;}for (int l = n - 2; l >= 1; l--) {if (nums[l] < nums[l + 1]) {dp[l + 1][0] = 1;dp[l + 1][1] = 1;} else {dp[l + 1][0] = 0;dp[l + 1][1] = 0;}for (int r = l + 2; r <= n; r++) {int a = 0;int b = 0;if (nums[l] < nums[l + 1]) {a = (a + dp[r][0]) % MOD;}if (nums[l] < nums[r]) {a = (a + dp[r][1]) % MOD;}if (nums[r] > nums[l]) {b = (b + dp[r - 1][0]) % MOD;}if (nums[r] > nums[r - 1]) {b = (b + dp[r - 1][1]) % MOD;}dp[r][0] = a;dp[r][1] = b;}}return (dp[n][0] + dp[n][1]) % MOD;}}

code4 546. 移除盒子

// 移除盒子
// 给出一些不同颜色的盒子boxes,盒子的颜色由不同的正数表示
// 你将经过若干轮操作去去掉盒子,直到所有的盒子都去掉为止
// 每一轮你可以移除具有相同颜色的连续 k 个盒子(k >= 1)
// 这样一轮之后你将得到 k * k 个积分
// 返回你能获得的最大积分总和
// 测试链接 : https://leetcode.cn/problems/remove-boxes/

boxes[l…r]范围上要去消除,前面跟着k个连续的和boxes[l]颜色一样的盒子
这种情况下,返回最大得分
int f(int[] boxes, int l, int r, int k)
1)前缀先消,尽量长
2)前缀跟后,枚举情况

package class077;// 移除盒子
// 给出一些不同颜色的盒子boxes,盒子的颜色由不同的正数表示
// 你将经过若干轮操作去去掉盒子,直到所有的盒子都去掉为止
// 每一轮你可以移除具有相同颜色的连续 k 个盒子(k >= 1)
// 这样一轮之后你将得到 k * k 个积分
// 返回你能获得的最大积分总和
// 测试链接 : https://leetcode.cn/problems/remove-boxes/
public class Code04_RemoveBoxes {// 时间复杂度O(n^4)public static int removeBoxes(int[] boxes) {int n = boxes.length;int[][][] dp = new int[n][n][n];return f(boxes, 0, n - 1, 0, dp);}// boxes[l....r]范围上要去消除,前面跟着k个连续的和boxes[l]颜色一样的盒子// 这种情况下,返回最大得分public static int f(int[] boxes, int l, int r, int k, int[][][] dp) {if (l > r) {return 0;}// l <= rif (dp[l][r][k] > 0) {return dp[l][r][k];}int s = l;while (s + 1 <= r && boxes[l] == boxes[s + 1]) {s++;}// boxes[l...s]都是一种颜色,boxes[s+1]就不是同一种颜色了// cnt是总前缀数量 : 之前的相同前缀(k个) + l...s这个颜色相同的部分(s-l+1个)int cnt = k + s - l + 1;// 可能性1 : 前缀先消int ans = cnt * cnt + f(boxes, s + 1, r, 0, dp);// 可能性2 : 讨论前缀跟着哪个后,一起消掉for (int m = s + 2; m <= r; m++) {if (boxes[l] == boxes[m] && boxes[m - 1] != boxes[m]) {// boxes[l] == boxes[m]是必须条件// boxes[m - 1] != boxes[m]是剪枝条件,避免不必要的调用ans = Math.max(ans, f(boxes, s + 1, m - 1, 0, dp) + f(boxes, m, r, cnt, dp));}}dp[l][r][k] = ans;return ans;}}

code5 1000. 合并石头的最低成本

// 合并石头的最低成本
// 有 n 堆石头排成一排,第 i 堆中有 stones[i] 块石头
// 每次 移动 需要将 连续的 k 堆石头合并为一堆,而这次移动的成本为这 k 堆中石头的总数
// 返回把所有石头合并成一堆的最低成本
// 如果无法合并成一堆返回-1
// 测试链接 : https://leetcode.cn/problems/minimum-cost-to-merge-stones/

(n-1)%(k-1)==0,才能合成1份

前1+(k-1)*z个合成1份
后面合成k-1份
最终k个合成1份
枚举z

package class077;// 合并石头的最低成本
// 有 n 堆石头排成一排,第 i 堆中有 stones[i] 块石头
// 每次 移动 需要将 连续的 k 堆石头合并为一堆,而这次移动的成本为这 k 堆中石头的总数
// 返回把所有石头合并成一堆的最低成本
// 如果无法合并成一堆返回-1
// 测试链接 : https://leetcode.cn/problems/minimum-cost-to-merge-stones/
public class Code05_MinimumCostToMergeStones {// 时间复杂度O(n^3)// 优化策略来自于观察// l.....r最终会变成几份其实是注定的,根本就无法改变// 那么也就知道,满足(n - 1) % (k - 1) == 0的情况下,// 0....n-1最终一定是1份,也无法改变// 如果l.....r最终一定是1份// 那么要保证l.....m最终一定是1份,m+1...r最终一定是k-1份// 如果l.....r最终一定是p份(p>1)// 那么要保证l.....m最终一定是1份,那么m+1...r最终一定是p-1份// 怎么保证的?枚举行为中,m += k-1很重要!// m每次跳k-1!// 如果l.....r最终一定是1份// 就一定能保证l.....m最终一定是1份// 也一定能保证m+1...r最终一定是k-1份// 不要忘了,加上最后合并成1份的代价// 如果l.....r最终一定是p份// 就一定能保证l.....m最终一定是1份// 也一定能保证m+1...r最终一定是p-1份// 不用加上最后合并成1份的代价public static int mergeStones(int[] stones, int k) {int n = stones.length;if ((n - 1) % (k - 1) != 0) {return -1;}int[] presum = new int[n + 1];// 多补了一个0位置,l...r累加和 : presum[r+1] - presum[l]for (int i = 0, j = 1, sum = 0; i < n; i++, j++) {sum += stones[i];presum[j] = sum;}// dp[l][r] : l...r范围上的石头,合并到不能再合并(份数是确定的),最小代价是多少int[][] dp = new int[n][n];for (int l = n - 2, ans; l >= 0; l--) {for (int r = l + 1; r < n; r++) {ans = Integer.MAX_VALUE;for (int m = l; m < r; m += k - 1) {ans = Math.min(ans, dp[l][m] + dp[m + 1][r]);}if ((r - l) % (k - 1) == 0) {// 最终一定能划分成一份,那么就再加合并代价ans += presum[r + 1] - presum[l];}dp[l][r] = ans;}}return dp[0][n - 1];}}

code6 730. 统计不同回文子序列

// 统计不同回文子序列
// 给你一个字符串s,返回s中不同的非空回文子序列个数
// 由于答案可能很大,请你将答案对10^9+7取余后返回
// 测试链接 : https://leetcode.cn/problems/count-different-palindromic-subsequences/

dp[i][j]:i…j有多少个不同的回文子序列
1)s[i]!=s[j]:dp[i][j-1]+dp[i+1][j]-dp[i+1][j-1]
2)s[i]==s[j]:
a:i…j中内部无a:dp[i+1][j-1]*2+2 ,*2是因为内部的回文子序列首尾添a依然是回文序列,+2是有a aa两个回文子序列
b:i…j中内部有1个a:dp[i+1][j-1]*2+1,+1是内部计算了a回文子序列
c:i…j中内部有不只1个a:dp[i+1][j-1]*2-dp[l+1][r-1],l是i右边最近的a位置,r是j左边最近的a位置,
因为[l+1,r-1]已经被(l,r)包过一次,所以不需要(i,j)再包1次。

package class077;import java.util.Arrays;// 统计不同回文子序列
// 给你一个字符串s,返回s中不同的非空回文子序列个数
// 由于答案可能很大,请你将答案对10^9+7取余后返回
// 测试链接 : https://leetcode.cn/problems/count-different-palindromic-subsequences/
public class Code06_CountDifferentPalindromicSubsequences {// 时间复杂度O(n^2)public static int countPalindromicSubsequences(String str) {int mod = 1000000007;char[] s = str.toCharArray();int n = s.length;int[] last = new int[256];// left[i] : i位置的左边和s[i]字符相等且最近的位置在哪,不存在就是-1int[] left = new int[n];Arrays.fill(last, -1);for (int i = 0; i < n; i++) {left[i] = last[s[i]];last[s[i]] = i;}// right[i] : i位置的右边和s[i]字符相等且最近的位置在哪,不存在就是nint[] right = new int[n];Arrays.fill(last, n);for (int i = n - 1; i >= 0; i--) {right[i] = last[s[i]];last[s[i]] = i;}// dp[i][j] : i...j范围上有多少不同的回文子序列// 如果i>j,那么认为是无效范围dp[i][j] = 0long[][] dp = new long[n][n];for (int i = 0; i < n; i++) {dp[i][i] = 1;}for (int i = n - 2, l, r; i >= 0; i--) {for (int j = i + 1; j < n; j++) {if (s[i] != s[j]) {// a ..... b// i       j// 因为要取模,所以只要发生减操作就+mod,讲解041同余原理dp[i][j] = dp[i][j - 1] + dp[i + 1][j] - dp[i + 1][j - 1] + mod;} else {// s[i] == s[j]// a......a// i      jl = right[i];r = left[j];if (l > r) {// i...j的内部没有s[i]字符// a....a// i    j// (i+1..j-1) + a(i+1..j-1)a + a + aadp[i][j] = dp[i + 1][j - 1] * 2 + 2;} else if (l == r) {// i...j的内部有一个s[i]字符// a.....a......a// i     lr     j// (i+1..j-1) + a(i+1..j-1)a + aadp[i][j] = dp[i + 1][j - 1] * 2 + 1;} else {// i...j的内部不只一个s[i]字符// a...a....这内部可能还有a但是不重要....a...a// i   l                             r   j// 因为要取模,所以只要发生减操作就+mod,讲解041同余原理dp[i][j] = dp[i + 1][j - 1] * 2 - dp[l + 1][r - 1] + mod;}}dp[i][j] %= mod;}}return (int) dp[0][n - 1];}}

2023-11-22 21:49:27

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/267752.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【触想智能】工业显示器的日常维护及分类知识分享

工业显示器不同于普通商业显示器&#xff0c;它的结构比较复杂&#xff0c;如果在使用的过程中出现产品故障&#xff0c;我们怎么处理呢?今天小编为大家介绍工业显示器日常维护以及分类方面的知识&#xff0c;希望对大家有所帮助。 1、 工业显示器整机无电。这其实是一个非常简…

2023年最新prometheus + grafana搭建和使用+gmail邮箱告警配置

一、安装prometheus 1.1 安装 prometheus官网下载地址 sudo -i mkdir -p /opt/prometheus #移动解压后的文件名到/opt/,并改名prometheus mv prometheus-2.45 /opt/prometheus/ #创建一个专门的prometheus用户&#xff1a; -M 不创建家目录&#xff0c; -s 不让登录 useradd…

新型生成式 AI 助手 Amazon Q 为 IT 专业人士与开发人员提供有力支持(预览版)

今天&#xff0c;我们发布 Amazon Q 预览版&#xff0c;这是一款专用于企业级业务的全新生成式 AI 助手&#xff0c;可根据客户的业务量身定制。 Amazon Q 为开发人员和 IT 专业人员带来了多种支持功能。现在&#xff0c;使用 Amazon Q&#xff0c;即可在亚马逊云科技上构建应…

计算机操作系统7

动态分区分配算法&#xff1a; 2.页表的逻辑地址和页内偏移量的计算 3. 两级页表 4.分段、分页管理的对比 5.传统存储方式的特征和缺点 6.虚拟存储 7.请求分页管理方式

2024世界燕窝滋补品展|上海燕博会推荐品牌天健燕窝集团-为消费者带来好燕窝!

天健燕窝集团拥有27年燕窝进出口贸易经验。是最早加入经营正规燕窝业务的企业之一&#xff0c;业务范围遍布全中国&#xff0c;2015 年至2019 年连续5年燕窝进口量全国第一。 一年一届的世界燕窝及天然滋补品博览会暨世界滋补生态发展大会&#xff08;简称上海燕博会&#xff…

IP与以太网的转发操作

TCP模块在执行连接、收发、断开等各阶段操作时&#xff0c;都需要委托IP模块将数据封装成包发送给通信对象。 网络中有路由器和集线器两种不同的转发设备&#xff0c;它们在传输网络包时有着各自的分工。 (1)路由器根据目标地址判断下一个路由器的位置 (2)集线器在子网中将网…

界面控件DevExpress中文教程 - 如何用Office File API组件填充PDF表单

DevExpress Office File API是一个专为C#, VB.NET 和 ASP.NET等开发人员提供的非可视化.NET库。有了这个库&#xff0c;不用安装Microsoft Office&#xff0c;就可以完全自动处理Excel、Word等文档。开发人员使用一个非常易于操作的API就可以生成XLS, XLSx, DOC, DOCx, RTF, CS…

友元c++

C快速入门 第二十讲&#xff1a;一种特殊的友情关系——友元关系 友元关系是类之间的一种特殊关系&#xff0c;这种关系不仅允许友元类访问对方的public方法和属性&#xff0c;还允许友元访问对方的protected和private方法和属性。 实例1&#xff1a;友元关系访问保护量 1 #i…

基于单片机的电阻、电容、电感测试仪(论文+源码)

1.系统设计 1)控制部分&#xff1a;本设计以单片机为核心&#xff0c;采用89C52单片机&#xff0c;利用其管脚的特殊功能以及所具备的中断系统&#xff0c;定时/计数器和LCD显示功能等。在本设计中&#xff0c;采用LCD1602液晶显示&#xff1a;本设计中有1个CD4502、3个LM555、…

Python使用分段函数拟合数据

Python使用分段函数拟合数据 前言前提条件相关介绍实验环境使用分段函数拟合数据代码实现输出结果 前言 由于本人水平有限&#xff0c;难免出现错漏&#xff0c;敬请批评改正。更多精彩内容&#xff0c;可点击进入Python日常小操作专栏、OpenCV-Python小应用专栏、YOLO系列专栏…

1,使用IDLE开启我们第一个Python程序

前面我们已经安装好了Python&#xff0c;安装了Python后&#xff0c;他会自动帮我们安装一个IDLE。IDLE是一个Python自带的非常简洁的集成开发环境&#xff08;IDE&#xff09;。他是一个Python Shell&#xff0c;我们可以利用Python Shell与Python交互。下面我们就利用IDLE开发…

【数据结构第 6 章 ②】- 用 C 语言实现邻接矩阵

目录 一、邻接矩阵表示法 二、AMGraph.h 三、AMGraph.c 四、Test.c 【数据结构第 6 章 ① 】- 图的定义和基本术语-CSDN博客 由于图的结构比较复杂&#xff0c;任意两个顶点之间都可能存在联系&#xff0c;因此无法以数据元素在存储区中的物理位置来表示元素之间的关系&…