Skip to content

Commit b7772b2

Browse files
committed
modify code
1 parent 8b14cdc commit b7772b2

File tree

4 files changed

+379
-0
lines changed

4 files changed

+379
-0
lines changed

src/class086/Code01_LCS.java

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
package class086;
2+
3+
// 最长公共子序列其中一个结果
4+
// 给定两个字符串str1和str2
5+
// 输出两个字符串的最长公共子序列
6+
// 如果最长公共子序列为空,则输出-1
7+
// 测试链接 : https://www.nowcoder.com/practice/4727c06b9ee9446cab2e859b4bb86bb8
8+
// 请同学们务必参考如下代码中关于输入、输出的处理
9+
// 这是输入输出处理效率很高的写法
10+
// 提交以下的code,提交时请把类名改成"Main",可以直接通过
11+
12+
import java.io.BufferedReader;
13+
import java.io.IOException;
14+
import java.io.InputStreamReader;
15+
import java.io.OutputStreamWriter;
16+
import java.io.PrintWriter;
17+
18+
// 讲解067 - 题目3,最长公共子序列长度
19+
public class Code01_LCS {
20+
21+
public static int MAXN = 5001;
22+
23+
public static int[][] dp = new int[MAXN][MAXN];
24+
25+
public static char[] ans = new char[MAXN];
26+
27+
public static char[] s1;
28+
29+
public static char[] s2;
30+
31+
public static int n, m, k;
32+
33+
public static void main(String[] args) throws IOException {
34+
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
35+
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
36+
s1 = br.readLine().toCharArray();
37+
s2 = br.readLine().toCharArray();
38+
n = s1.length;
39+
m = s2.length;
40+
lcs();
41+
if (k == 0) {
42+
out.println(-1);
43+
} else {
44+
for (int i = 0; i < k; i++) {
45+
out.print(ans[i]);
46+
}
47+
out.println();
48+
}
49+
out.flush();
50+
out.close();
51+
br.close();
52+
}
53+
54+
public static void lcs() {
55+
dp();
56+
k = dp[n][m];
57+
if (k > 0) {
58+
for (int len = k, i = n, j = m; len > 0;) {
59+
if (s1[i - 1] == s2[j - 1]) {
60+
ans[--len] = s1[i - 1];
61+
i--;
62+
j--;
63+
} else {
64+
if (dp[i - 1][j] >= dp[i][j - 1]) {
65+
i--;
66+
} else {
67+
j--;
68+
}
69+
}
70+
}
71+
}
72+
}
73+
74+
// 填好dp表
75+
public static void dp() {
76+
for (int i = 1; i <= n; i++) {
77+
for (int j = 1; j <= m; j++) {
78+
if (s1[i - 1] == s2[j - 1]) {
79+
dp[i][j] = 1 + dp[i - 1][j - 1];
80+
} else {
81+
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
82+
}
83+
}
84+
}
85+
}
86+
87+
}

src/class086/Code02_LIS.java

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
package class086;
2+
3+
// 最长递增子序列字典序最小的结果
4+
// 给定数组arr,设长度为n
5+
// 输出arr的最长递增子序列
6+
// 如果有多个答案,请输出其中字典序最小的
7+
// 字典序设定 :
8+
// 每个数字看作是单独的字符,比如120认为比36的字典序大
9+
// 测试链接 : https://www.nowcoder.com/practice/30fb9b3cab9742ecae9acda1c75bf927
10+
// 请同学们务必参考如下代码中关于输入、输出的处理
11+
// 这是输入输出处理效率很高的写法
12+
// 提交以下的code,提交时请把类名改成"Main",可以直接通过
13+
14+
import java.io.BufferedReader;
15+
import java.io.IOException;
16+
import java.io.InputStreamReader;
17+
import java.io.OutputStreamWriter;
18+
import java.io.PrintWriter;
19+
import java.io.StreamTokenizer;
20+
import java.util.Arrays;
21+
22+
// 讲解072 - 最长递增子序列及其扩展
23+
public class Code02_LIS {
24+
25+
public static int MAXN = 100001;
26+
27+
public static int[] nums = new int[MAXN];
28+
29+
public static int[] ends = new int[MAXN];
30+
31+
public static int[] dp = new int[MAXN];
32+
33+
public static int[] ans = new int[MAXN];
34+
35+
public static int n, k;
36+
37+
public static void main(String[] args) throws IOException {
38+
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
39+
StreamTokenizer in = new StreamTokenizer(br);
40+
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
41+
while (in.nextToken() != StreamTokenizer.TT_EOF) {
42+
n = (int) in.nval;
43+
for (int i = 0; i < n; i++) {
44+
in.nextToken();
45+
nums[i] = (int) in.nval;
46+
}
47+
lis();
48+
for (int i = 0; i < k - 1; i++) {
49+
out.print(ans[i] + " ");
50+
}
51+
out.println(ans[k - 1]);
52+
}
53+
out.flush();
54+
out.close();
55+
br.close();
56+
}
57+
58+
public static void lis() {
59+
k = dp();
60+
Arrays.fill(ans, 0, k, Integer.MAX_VALUE);
61+
for (int i = 0; i < n; i++) {
62+
if (dp[i] == k) {
63+
if (nums[i] < ans[0]) {
64+
ans[0] = nums[i];
65+
}
66+
} else {
67+
if (ans[k - dp[i] - 1] < nums[i] && nums[i] < ans[k - dp[i]]) {
68+
ans[k - dp[i]] = nums[i];
69+
}
70+
}
71+
}
72+
}
73+
74+
// dp[i] : 必须以i位置的数字开头的情况下,最长递增子序列长度
75+
// 填好dp表 + 返回最长递增子序列长度
76+
public static int dp() {
77+
int len = 0;
78+
for (int i = n - 1, find; i >= 0; i--) {
79+
find = bs(len, nums[i]);
80+
if (find == -1) {
81+
ends[len++] = nums[i];
82+
dp[i] = len;
83+
} else {
84+
ends[find] = nums[i];
85+
dp[i] = find + 1;
86+
}
87+
}
88+
return len;
89+
}
90+
91+
public static int bs(int len, int num) {
92+
int l = 0, r = len - 1, m, ans = -1;
93+
while (l <= r) {
94+
m = (l + r) / 2;
95+
if (ends[m] <= num) {
96+
ans = m;
97+
r = m - 1;
98+
} else {
99+
l = m + 1;
100+
}
101+
}
102+
return ans;
103+
}
104+
105+
}

src/class086/Code03_Diving.java

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
package class086;
2+
3+
// 潜水的最大时间与方案
4+
// 一共有n个工具,每个工具都有自己的重量a、阻力b、提升的停留时间c
5+
// 因为背包有限,所以只能背重量不超过m的工具
6+
// 因为力气有限,所以只能背阻力不超过v的工具
7+
// 希望能在水下停留的时间最久
8+
// 返回最久的停留时间和下标字典序最小的选择工具的方案
9+
// 字典序设定 :
10+
// 下标的数值认为是字符串,比如下标120认为比下标36的字典序小
11+
// 测试链接 : https://www.luogu.com.cn/problem/P1759
12+
// 请同学们务必参考如下代码中关于输入、输出的处理
13+
// 这是输入输出处理效率很高的写法
14+
// 提交以下的code,提交时请把类名改成"Main",可以直接通过
15+
16+
import java.io.BufferedReader;
17+
import java.io.IOException;
18+
import java.io.InputStreamReader;
19+
import java.io.OutputStreamWriter;
20+
import java.io.PrintWriter;
21+
import java.io.StreamTokenizer;
22+
23+
// 讲解069 - 多维费用背包 + 空间压缩
24+
public class Code03_Diving {
25+
26+
public static int MAXN = 101;
27+
28+
public static int MAXM = 201;
29+
30+
public static int[] a = new int[MAXN];
31+
32+
public static int[] b = new int[MAXN];
33+
34+
public static int[] c = new int[MAXN];
35+
36+
public static int[][] dp = new int[MAXM][MAXM];
37+
38+
public static String[][] path = new String[MAXM][MAXM];
39+
40+
public static int m, v, n;
41+
42+
public static void build() {
43+
for (int i = 0; i <= m; i++) {
44+
for (int j = 0; j <= v; j++) {
45+
dp[i][j] = 0;
46+
path[i][j] = null;
47+
}
48+
}
49+
}
50+
51+
public static void main(String[] args) throws IOException {
52+
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
53+
StreamTokenizer in = new StreamTokenizer(br);
54+
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
55+
while (in.nextToken() != StreamTokenizer.TT_EOF) {
56+
m = (int) in.nval;
57+
in.nextToken();
58+
v = (int) in.nval;
59+
in.nextToken();
60+
n = (int) in.nval;
61+
build();
62+
for (int i = 1; i <= n; i++) {
63+
in.nextToken();
64+
a[i] = (int) in.nval;
65+
in.nextToken();
66+
b[i] = (int) in.nval;
67+
in.nextToken();
68+
c[i] = (int) in.nval;
69+
}
70+
compute();
71+
out.println(dp[m][v]);
72+
out.println(path[m][v]);
73+
}
74+
out.flush();
75+
out.close();
76+
br.close();
77+
}
78+
79+
// 这个方法就是讲了很多遍的空间压缩技巧
80+
// 请务必掌握动态规划前几节课对这一技巧的讲解
81+
public static void compute() {
82+
String cur;
83+
for (int i = 1; i <= n; i++) {
84+
for (int j = m; j >= a[i]; j--) {
85+
for (int k = v; k >= b[i]; k--) {
86+
if (path[j - a[i]][k - b[i]] == null) {
87+
cur = String.valueOf(i);
88+
} else {
89+
cur = path[j - a[i]][k - b[i]] + " " + String.valueOf(i);
90+
}
91+
if (dp[j][k] < dp[j - a[i]][k - b[i]] + c[i]) {
92+
dp[j][k] = dp[j - a[i]][k - b[i]] + c[i];
93+
path[j][k] = cur;
94+
} else if (dp[j][k] == dp[j - a[i]][k - b[i]] + c[i]) {
95+
if (cur.compareTo(path[j][k]) < 0) {
96+
path[j][k] = cur;
97+
}
98+
}
99+
}
100+
}
101+
}
102+
}
103+
104+
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package class086;
2+
3+
import java.util.Arrays;
4+
import java.util.List;
5+
6+
// 最小的必要团队
7+
// 作为项目经理,你规划了一份需求的技能清单req_skills
8+
// 并打算从备选人员名单people中选出些人组成必要团队
9+
// 编号为i的备选人员people[i]含有一份该备选人员掌握的技能列表
10+
// 所谓必要团队,就是在这个团队中
11+
// 对于所需求的技能列表req_skills中列出的每项技能,团队中至少有一名成员已经掌握
12+
// 请你返回规模最小的必要团队,团队成员用人员编号表示
13+
// 你可以按 任意顺序 返回答案,题目数据保证答案存在
14+
// 测试链接 : https://leetcode.cn/problems/smallest-sufficient-team/
15+
public class Code04_SmallestSufficientTeam {
16+
17+
// 讲解080、081 - 状压dp
18+
public static int[] smallestSufficientTeam(String[] skills, List<List<String>> people) {
19+
Arrays.sort(skills);
20+
int n = skills.length;
21+
int m = people.size();
22+
int[] arr = new int[m];
23+
for (int i = 0; i < m; i++) {
24+
int status = 0;
25+
List<String> skill = people.get(i);
26+
skill.sort((a, b) -> a.compareTo(b));
27+
int p1 = 0;
28+
int p2 = 0;
29+
while (p1 < n && p2 < skill.size()) {
30+
int compare = skills[p1].compareTo(skill.get(p2));
31+
if (compare < 0) {
32+
p1++;
33+
} else if (compare > 0) {
34+
p2++;
35+
} else {
36+
status |= 1 << p1;
37+
p1++;
38+
p2++;
39+
}
40+
}
41+
arr[i] = status;
42+
}
43+
int[][] dp = new int[m][1 << n];
44+
for (int i = 0; i < m; i++) {
45+
Arrays.fill(dp[i], -1);
46+
}
47+
int size = f(arr, n, 0, 0, dp);
48+
int[] ans = new int[size];
49+
int ansi = 0;
50+
int i = 0;
51+
int status = 0;
52+
while (status != (1 << n) - 1) {
53+
if (i + 1 == m || dp[i][status] != dp[i + 1][status]) {
54+
ans[ansi++] = i;
55+
status |= arr[i];
56+
}
57+
i++;
58+
}
59+
return ans;
60+
}
61+
62+
public static int f(int[] arr, int n, int i, int status, int[][] dp) {
63+
if (status == (1 << n) - 1) {
64+
return 0;
65+
}
66+
if (i == arr.length) {
67+
return Integer.MAX_VALUE;
68+
}
69+
if (dp[i][status] != -1) {
70+
return dp[i][status];
71+
}
72+
int p1 = f(arr, n, i + 1, status, dp);
73+
int p2 = Integer.MAX_VALUE;
74+
int next2 = f(arr, n, i + 1, status | arr[i], dp);
75+
if (next2 != Integer.MAX_VALUE) {
76+
p2 = 1 + next2;
77+
}
78+
int ans = Math.min(p1, p2);
79+
dp[i][status] = ans;
80+
return ans;
81+
}
82+
83+
}

0 commit comments

Comments
 (0)