算法分析与设计 实验5 算法的综合实验

实验5 算法的综合实验

专业班级:计算机科学与技术165班

课程名称:算法分析与设计实验

一、矩阵迷宫中的最短通道

1、分析

  • 此题为课本中9.3.1节的矩阵迷宫中的最短通道问题。
  • 课本中使用的是dp(动态规划)方法,我用带回溯的bfs(广度优先搜索)重写了一遍。为了比较两种方法的差异(运行时间),我把迷宫大小扩大了很多倍。为了从文件读取数据方便,我省略的数据中的空格。
  • 思路是:由于bfs是一步一步往外扩散,故第一次取得的就是最少步数。从文件读取迷宫到maze。定义一个Node类,内含当前步数step、前驱位置pre、当前位置x,y。用方向向量int X[],int Y[] 表示四个方向。q为bfs所用的队列。boolean vis[][]标记某个位置是否走过,防止回头。当走到某个位置,用check(int x,int y)方法检查是否合法,若是,则继续走。若到达终点,用find(int n)方法初始化迷宫中的路径,在打印出来。
  • 除了课本上的示例数据,我还随机生成了几个不同规格的迷宫,用于测试。
  • 经过测试,dp比bfs稍快一点,但是bfs显然是这类问题最容易想到且最易实现的方法。

2、修改

(1).dp(动态规划)
package 算法设计;

import java.io.*;
import java.util.Scanner;

public class 迷宫 {
	static Scanner in = new Scanner(System.in);
	static int n, m;
	static int[][] a = new int[200][200];
	static int[][] b = new int[200][200];
	static int[][] c = new int[200][200];
	static int[][] f = new int[200][200];
	static int d, e;

	public static void main(String[] args) throws FileNotFoundException {
		long time = System.currentTimeMillis();
		Scanner in = new Scanner(new File("src/算法设计/4.txt"));
		n = in.nextInt();
		m = in.nextInt();
		System.out.println(n + "行 " + m + "列");
		for (int i = 1; i <= n; ++i) {
			String temp = in.next();
			for (int j = 1; j <= m; ++j) {
				a[i][j] = temp.charAt(j - 1) == '1' ? 1 : 0;
			}
		}

		b[n][m] = 1;
		for (int j = m - 1; j >= 1; j--) // 最下行b,c数组赋初值
			if (a[n][j] == 0 && a[n][j + 1] == 0) {
				b[n][j] = b[n][j + 1] + 1;
				c[n][j] = n * 100 + j + 1;
			} else
				b[n][j] = m * n;

		for (int i = n - 1; i >= 1; i--) // 最右列b,c数组赋初值
			if (a[i][m] == 0 && a[i + 1][m] == 0) {
				b[i][m] = b[i + 1][m] + 1;
				c[i][m] = (i + 1) * 100 + m;
			} else
				b[i][m] = m * n;

		for (int i = n - 1; i >= 1; i--) // 与右、下比较初步逆推得b[i][j]
			for (int j = m - 1; j >= 1; j--)
				if (a[i][j] == 0) {
			if (b[i + 1][j] < b[i][j + 1] && b[i + 1][j] < n * m) {
						b[i][j] = b[i + 1][j] + 1;
						c[i][j] = (i + 1) * 100 + j;
					}
			if (b[i + 1][j] >= b[i][j + 1] && b[i][j + 1] < n * m) {
						b[i][j] = b[i][j + 1] + 1;
						c[i][j] = i * 100 + j + 1;
					}
			if (b[i + 1][j] >= n * m && b[i][j + 1] >= n * m)
						b[i][j] = n * m;
				} else
					b[i][j] = m * n;
		int t = 1;
		while (t > 0) { // 每一格与四周比较,逐步优化调整
			t = 0;
			for (int i = n; i >= 1; i--)
				for (int j = m; j >= 1; j--)
					if (!(i == n && j == m) && a[i][j] == 0) {
						d = b[i][j];
				if (j > 1 && b[i][j - 1] + 1 < d) { // 与右格比较
							d = 1 + b[i][j - 1];
							c[i][j] = i * 100 + j - 1;
							t = 1;
						}
				if (j < m && b[i][j + 1] + 1 < d) { // 与左格比较
							d = 1 + b[i][j + 1];
							c[i][j] = i * 100 + j + 1;
							t = 1;
						}
				if (i > 1 && b[i - 1][j] + 1 < d) { // 与上格比较
							d = 1 + b[i - 1][j];
							c[i][j] = (i - 1) * 100 + j;
							t = 1;
						}
				if (i < n && b[i + 1][j] + 1 < d) { // 与下格比较
							d = 1 + b[i + 1][j];
							c[i][j] = (i + 1) * 100 + j;
							t = 1;
						}
						b[i][j] = d;
					}
		}
		if (b[1][1] >= m * n) {
			System.out.println(" 此迷宫不存在通道! ");
			return;
		}

		System.out.println(" 最短通道格数为: " + b[1][1]);// 输出最短通道格数
		System.out.println(" 一条最短通道为: ");// 输出一条最小的路径
		int p = 1;
		int q = 1;
		f[1][1] = 1;
		while (p < n || q < m) {
			e = c[p][q];
			p = e / 100;
			q = e % 100;
			f[p][q] = 1;
		}
		for (int i = 1; i <= n; i++) {
			for (int j = 1; j <= m; j++)
				if (f[i][j] == 1)
					System.out.printf("%4d", b[1][1] - b[i][j] + 1);
				else
					System.out.print("    ");
			System.out.println();
		}
		System.out.println((System.currentTimeMillis() - time) + "ms");
	}
}
(2).bfs(广度优先搜索)
package 算法设计;

import java.io.*;
import java.util.*;

class Node {
	int step;
	int pre;
	int x, y;

	public Node(int step, int pre, int x, int y) {
		super();
		this.step = step;
		this.pre = pre;
		this.x = x;
		this.y = y;
	}
}

public class 迷宫 {
	static Scanner in = new Scanner(System.in);
	static int n, m;
	static int[][] maze = new int[200][200];
	static boolean[][] vis = new boolean[200][200];
	static int[] X = { 1, 0, 0, -1 };// 增量数组,方向向量
	static int[] Y = { 0, -1, 1, 0 };
	static Node[] q = new Node[100000000];

	public static void main(String[] args) throws FileNotFoundException {
		long time = System.currentTimeMillis();
		Scanner in = new Scanner(new File("src/算法设计/4.txt"));
		n = in.nextInt();
		m = in.nextInt();
		System.out.println(n + "行 " + m + "列");
		for (int i = 1; i <= n; ++i) {
			String temp = in.next();
			for (int j = 1; j <= m; ++j)
				maze[i][j] = temp.charAt(j - 1) == '1' ? -1 : 0;
		}
		bfs();
		System.out.println((System.currentTimeMillis() - time) + "ms");
	}

	static boolean check(int x, int y) {
		if (x < 1 || x > n || y < 1 || y > m)
			return false;
		if (vis[x][y] || maze[x][y] == -1)
			return false;
		return true;
	}

	static void find(int n) {
		if (q[n].pre != -1)
			find(q[n].pre);

		maze[q[n].x][q[n].y] = q[n].step;
	}

	static void bfs() {
		int left = 0;
		int right = 0;
		q[right++] = new Node(1, -1, 1, 1);

		while (left < right) {
			Node top = q[left++];
			vis[top.x][top.y] = true;
			if (top.x == n && top.y == m) {
			// 输出最短通道格数
			System.out.println(" 最短通道格数为: " + top.step);
			// 输出一条最小的路径
			System.out.println(" 一条最短通道为: ");
				find(left - 1);

				for (int i = 1; i <= n; i++) {
					for (int j = 1; j <= m; j++) {
					if (maze[i][j] == -1 || maze[i][j] == 0)
						System.out.printf("    ");
					else
					System.out.printf("%4d", maze[i][j]);
					}
					System.out.println();
				}
				return;
			}
			for (int i = 0; i < 4; ++i) {
				int newX = top.x + X[i];
				int newY = top.y + Y[i];
			if (check(newX, newY)) {
		q[right++] = new Node(top.step + 1, left - 1, newX, newY);
			}
			}
		}
		System.out.println(" 此迷宫不存在通道! ");
	}
}

3、测试

  • 下面为两种方法运行课本中示例数据结果截图。
(1)、dp

在这里插入图片描述

(2)、bfs

在这里插入图片描述

(3)、测试数据
①12行 11列

01000010001
01001000101
00100111000
10110100110
00100100000
01101101100
00101100010
10100011001
00110010000
01000100111
01010101000
00010100010

②30行 50列

01010101001011001001010110010110100100001000101010
00001000100000101010010000100000001001100110100101
01111011010010001000001101001011100011000000010000
01000000001010100011010000101000001010101011001011
00011111000000101000010010100010100000101100000000
11001000110101000010101100011010011010101011110111
00011011010101001001001010000001000101001110000000
10100000101000100110101010111110011000010000111010
00111000001010100001100010000001000101001100001001
11000110100001110010001001010101010101010001101000
00010000100100000101001010101110100010101010000101
11100100101001001000010000010101010100100100010100
00000010000000101011001111010001100000101010100011
10101010011100001000011000010110011110110100001000
10101010100001101010100101000010100000111011101001
10000000101100010000101100101101001011100000000100
10101001000000010100100001000100000100011110101001
00101001010101101001010100011010101101110000110101
11001010000100001100000010100101000001000111000010
00001000110000110101101000000100101001001000011101
10100101000101000000001110110010110101101010100001
00101000010000110101010000100010001001000100010101
10100001000110010001000010101001010101011111010010
00000100101000000110010100101001000001000000000010
11010000001001110111001001000011101001011011101000
00000110100010001000100000001000011101000000110011
10101000101000100010001111100010101001010000001000
10000010100101001010110000000100101010001011101000
00111100001000010000000110111000000001000000001011
10000001100111010111010001000110111010101101111000

③120行 50列

01010101001011001001010110010110100100001000101010
00001000100000101010010000100000001001100110100101
01111011010010001000001101001011100011000000010000
01000000001010100011010000101000001010101011001011
00011111000000101000010010100010100000101100000000
11001000110101000010101100011010011010101011110111
00011011010101001001001010000001000101001110000000
10100000101000100110101010111110011000010000111010
00111000001010100001100010000001000101001100001001
11000110100001110010001001010101010101010001101000
00010000100100000101001010101110100010101010000101
11100100101001001000010000010101010100100100010100
00000010000000101011001111010001100000101010100011
10101010011100001000011000010110011110110100001000
10101010100001101010100101000010100000111011101001
10000000101100010000101100101101001011100000000100
10101001000000010100100001000100000100011110101001
00101001010101101001010100011010101101110000110101
11001010000100001100000010100101000001000111000010
00001000110000110101101000000100101001001000011101
10100101000101000000001110110010110101101010100001
00101000010000110101010000100010001001000100010101
10100001000110010001000010101001010101011111010010
00000100101000000110010100101001000001000000000010
11010000001001110111001001000011101001011011101000
00000110100010001000100000001000011101000000110011
10101000101000100010001111100010101001010000001000
10000010100101001010110000000100101010001011101000
00111100001000010000000110111000000001000000001011
10000001100111010111010001000110111010101101111000
01010101001011001001010110010110100100001000101010
00001000100000101010010000100000001001100110100101
01111011010010001000001101001011100011000000010000
01000000001010100011010000101000001010101011001011
00011111000000101000010010100010100000101100000000
11001000110101000010101100011010011010101011110111
00011011010101001001001010000001000101001110000000
10100000101000100110101010111110011000010000111010
00111000001010100001100010000001000101001100001001
11000110100001110010001001010101010101010001101000
00010000100100000101001010101110100010101010000101
11100100101001001000010000010101010100100100010100
00000010000000101011001111010001100000101010100011
10101010011100001000011000010110011110110100001000
10101010100001101010100101000010100000111011101001
10000000101100010000101100101101001011100000000100
10101001000000010100100001000100000100011110101001
00101001010101101001010100011010101101110000110101
11001010000100001100000010100101000001000111000010
00001000110000110101101000000100101001001000011101
10100101000101000000001110110010110101101010100001
00101000010000110101010000100010001001000100010101
10100001000110010001000010101001010101011111010010
00000100101000000110010100101001000001000000000010
11010000001001110111001001000011101001011011101000
00000110100010001000100000001000011101000000110011
10101000101000100010001111100010101001010000001000
10000010100101001010110000000100101010001011101000
00111100001000010000000110111000000001000000001011
10000001100111010111010001000110111010101101111000
01010101001011001001010110010110100100001000101010
00001000100000101010010000100000001001100110100101
01111011010010001000001101001011100011000000010000
01000000001010100011010000101000001010101011001011
00011111000000101000010010100010100000101100000000
11001000110101000010101100011010011010101011110111
00011011010101001001001010000001000101001110000000
10100000101000100110101010111110011000010000111010
00111000001010100001100010000001000101001100001001
11000110100001110010001001010101010101010001101000
00010000100100000101001010101110100010101010000101
11100100101001001000010000010101010100100100010100
00000010000000101011001111010001100000101010100011
10101010011100001000011000010110011110110100001000
10101010100001101010100101000010100000111011101001
10000000101100010000101100101101001011100000000100
10101001000000010100100001000100000100011110101001
00101001010101101001010100011010101101110000110101
11001010000100001100000010100101000001000111000010
00001000110000110101101000000100101001001000011101
10100101000101000000001110110010110101101010100001
00101000010000110101010000100010001001000100010101
10100001000110010001000010101001010101011111010010
00000100101000000110010100101001000001000000000010
11010000001001110111001001000011101001011011101000
00000110100010001000100000001000011101000000110011
10101000101000100010001111100010101001010000001000
10000010100101001010110000000100101010001011101000
00111100001000010000000110111000000001000000001011
10000001100111010111010001000110111010101101111000
01010101001011001001010110010110100100001000101010
00001000100000101010010000100000001001100110100101
01111011010010001000001101001011100011000000010000
01000000001010100011010000101000001010101011001011
00011111000000101000010010100010100000101100000000
11001000110101000010101100011010011010101011110111
00011011010101001001001010000001000101001110000000
10100000101000100110101010111110011000010000111010
00111000001010100001100010000001000101001100001001
11000110100001110010001001010101010101010001101000
00010000100100000101001010101110100010101010000101
11100100101001001000010000010101010100100100010100
00000010000000101011001111010001100000101010100011
10101010011100001000011000010110011110110100001000
10101010100001101010100101000010100000111011101001
10000000101100010000101100101101001011100000000100
10101001000000010100100001000100000100011110101001
00101001010101101001010100011010101101110000110101
11001010000100001100000010100101000001000111000010
00001000110000110101101000000100101001001000011101
10100101000101000000001110110010110101101010100001
00101000010000110101010000100010001001000100010101
10100001000110010001000010101001010101011111010010
00000100101000000110010100101001000001000000000010
11010000001001110111001001000011101001011011101000
00000110100010001000100000001000011101000000110011
10101000101000100010001111100010101001010000001000
10000010100101001010110000000100101010001011101000
00111100001000010000000110111000000001000000001011
10000001100111010111010001000110111010101101111000

4、比较

  • 下面是两种方法在不同迷宫规格下分别运行5次所用时间记录。
迷宫规格12行 11列
测试次数dp(ms)bfs(ms)
13432
22523
32841
42124
54326
迷宫规格30行 50列
测试次数dp(ms)bfs(ms)
15289
28396
36185
491118
55983
迷宫规格120行 50列
测试次数dp(ms)bfs(ms)
184383
288338
399445
4166426
5104359
  • 容易看出:两种方法在迷宫规格较小时运行时间相差不大。但随着迷宫规格的扩大,dp法运行渐渐比bfs块。我还测试了一组120行100列的迷宫,但是两种方法均长时间得不出结果,故未列出运行结果。
  • 经测试,两种方法的极限迷宫规格是基本一样的,既有效数据范围一致。虽然bfs在数据较大时运行稍慢,约为课本上dp的4倍,但是bfs更容易想到,且更易实现,是解决这类问题的首选。并且,两种方法只要在有效数据范围内效率相差并不大,因此我觉得bfs是一种更好的方法。

二、三角数阵中的最小路径

1、分析

  • 此题为课本中9.3.2节的矩阵迷宫中的三角数阵中的最小路径问题。
  • 思路是:用dp法。设(i,j)为数阵中第i行第j列所在格,二维数组a[i][j]存储(i,j)格中的数。int[][] b为从(i,j)格至底行格路径的最小数值和。显然最优路径的数值和为b[i][j]。int[][] f,若(i,j)在最优路径上则f[i][j]为1。初始b[n][i]=a[n][j]。

2、代码

package 实验8算法的综合实验;

import java.io.*;
import java.util.*;

public class 三角数阵中的最小路径 {
	static Scanner in = new Scanner(System.in);
	static int d, e, n, i, j, t;
	static int N = 100;
	static int[][] a = new int[N][N];
	static int[][] b = new int[N][N];
	static int[][] c = new int[N][N];
	static int[][] f = new int[N][N];

	public static void main(String[] args) throws FileNotFoundException {
		long time = System.currentTimeMillis();
		Scanner in = new Scanner(new File("src/实验8算法的综合实验/2.txt"));
		n = in.nextInt();
		System.out.println("三角形数阵行数: " + n);

		for (int i = 1; i <= n; i++) {
			for (int j = 1; j <= 36 - 2 * i; j++)
				System.out.print(" ");
			for (int j = 1; j <= i; j++) {
				f[i][j] = 0;
				a[i][j] = (int) (1 + Math.random() * 49);// 从文件读数据到二维a数组
				System.out.printf("%4d", a[i][j]);
			}
			System.out.printf("\n");
		}
		for (j = 1; j <= n; j++)
			b[n][j] = a[n][j];
		for (i = n - 1; i >= 1; i--) // 逆推得b[i][j]
			for (j = 1; j <= i; j++)
				if (b[i + 1][j + 1] < b[i + 1][j]) {
					b[i][j] = a[i][j] + b[i + 1][j + 1];
					c[i][j] = (i + 1) * 100 + j + 1;
				} else {
					b[i][j] = a[i][j] + b[i + 1][j];
					c[i][j] = (i + 1) * 100 + j;
				}
		t = 1;
		while (t > 0) {
			t = 0;
			for (i = n - 1; i >= 1; i--) // 各b数组元素调整优化
				for (j = i; j >= 1; j--) {
					d = b[i][j];
					if (j > 1 && b[i][j - 1] + a[i][j] < d) // 与同行左格比较
					{
						d = a[i][j] + b[i][j - 1];
						c[i][j] = i * 100 + j - 1;
						t = 1;
					}
					if (j < i && b[i][j + 1] + a[i][j] < d) // 与同行右格比较
					{
						d = a[i][j] + b[i][j + 1];
						c[i][j] = i * 100 + j + 1;
						t = 1;
					}
					if (i > 1 && j < i && b[i - 1][j] + a[i][j] < d) // 与右上格比较
					{
						d = a[i][j] + b[i - 1][j];
						c[i][j] = (i - 1) * 100 + j;
						t = 1;
					}
					if (i > 1 && j > 1 && b[i - 1][j - 1] + a[i][j] < d) // 与左上格比较
					{
						d = a[i][j] + b[i - 1][j - 1];
						c[i][j] = (i - 1) * 100 + j - 1;
						t = 1;
					}
					if (i < n && b[i + 1][j] + a[i][j] < d) // 与左下格比较
					{
						d = a[i][j] + b[i + 1][j];
						c[i][j] = (i + 1) * 100 + j;
						t = 1;
					}
					if (i < n && b[i + 1][j + 1] + a[i][j] < d) // 与右下格比较
					{
						d = a[i][j] + b[i + 1][j + 1];
						c[i][j] = (i + 1) * 100 + j + 1;
						t = 1;
					}
					b[i][j] = d;
				}
		}
		System.out.printf("  最小路径数值和为:%d\n", b[1][1]); // 输出最小数字和
		System.out.printf("  最小路径为:\n");
		i = 1;
		j = 1;
		f[i][j] = 1;
		while (i < n) {
			e = c[i][j];
			i = e / 100;
			j = e % 100;
			f[i][j] = 1;
		}
		for (i = 1; i <= n; i++) {// 输出和最小的路径
		
			for (j = 1; j <= 36 - 2 * i; j++)
				System.out.printf(" ");
			for (j = 1; j <= i; j++)
				if (f[i][j] == 1)
					System.out.printf("%3d ", a[i][j]);
				else
					System.out.printf(" -- ");
			System.out.printf("\n");
		}

		System.out.println("\n" + (System.currentTimeMillis() - time) + "ms");
	}
}

3、测试

  • 下面为3组数据以及结果截图,其中测试1为课本数据,测试2、3为随机生成数据。
(1).测试1
                                     1
                                  40   1
                                 1   1  40
                               1  40  40   1
                            40   1  40   3   1
                          40  40   2   1  40   1
                        40  40  40  40  40  40   1
                      40  40  40   1   5  40  40   1
                     1   7  40   1  40   1  40  40   1
                   1  40   1   6  40  40   1   1   4  40
                40   1  40  40  40  40  40  40  40  40  40
              40  20  40  40  40  40  40  40  40  40  40  40

在这里插入图片描述

(2).测试2(n=20)
                                    26
                                  12  20
                                27  26  27
                              12  43   7  19
                            46  17  34   1   2
                          16  36  21  22  38  20
                        28  46  27  35   5  21  27
                      30   5  11  49  38  35  49  45
                    20  36  46  37  47  25  45  21  34
                  33  32  45  42  34   8  32  24   2  15
                49   7  47   8  39   6  24  36  13  15   4
              47  12  21  31  43  35  34   4  35   3  39  26
            37  32  34  49  24  39  41  30  35  24  48   4  18
          38  27   1  26  33  12  18  49   3  36   4  12  42  23
        20  14   2  43  29  49  14   2  49  49  26  32  41   7  26
      47  10   4  17  40  33  27  40  12  31  25  11  11  15  27  19
     2   9  19  15  13   9  15   2   5  30   3  24  29  17  16  30  35
  17  19  36  26  15  20  38   6  40   1  28   1   2  25  43  13  48  49
  40  14  34  43  21  49  45  26  14  22  17  39  24  15  27  43  26  35  30
  33   8  27  49  42  21  12  49  14  33  49  48   4  47   8  30  19   7  33  27

在这里插入图片描述

(3).测试3(n=99)

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
0 1背包问题是一例典型的组合优化的NP完全问题 问题可以描述为:给定一组共n个物品 每种物品都有自己的重量wi i 1 n和价值vi i 1 n 在限定的总重量(背包的容量C)内 如何选择才能使得选择物品的总价值之和最高 选择最优的物品子集放置于给定背包中 最优子集对应n元解向量 x1 …xn xi∈{0或1} 因此命名为0 1背包问题 0 1背包问题是许多问题的原型 但它又是一个NP完全问题 此实验主要研究和实现n 0< n< 200 和C C< 2000 C为整数 都较大的情形 随机产生n个物品的重量向量wi 1< wi< 100 wi为整数 和价值向量vi 1< vi< 100 vi为整数 0 1背包问题可以用许多方法来求解 有些算法可以得到问题的精确最优解 有些仅能获得一个近似最优解 本综合设计实验要求用3种以上的方法求解0 1背包问题 获得精确最优解或近似最优解皆可 并对所采用的多种算法从运行时间 寻找是否为最优解 能够求解的问题规模等方面进行对比和分析 本课程讲述的所有算法思想都可以用来求解此问题 甚至本课程未涉及的许多算法也非常适合于求解此问题 学生可以先尝试先用本课程已介绍的算法来实现和分析 学有余力或兴趣驱动下可以寻找一些智能算法的资料来试一试 涉及的方法可以有:蛮力求解 递归求解 动态规划求解 贪心求解 回溯法求解 广度优先的分支限界法求解 优先队列的启发式分支限界法 遗传算法 模拟退火算法 蚁群算法 粒子群算法等 ">0 1背包问题是一例典型的组合优化的NP完全问题 问题可以描述为:给定一组共n个物品 每种物品都有自己的重量wi i 1 n和价值vi i 1 n 在限定的总重量(背包的容量C)内 如何选择才能使得选择物品的总价值之和最高 选择 [更多]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值