作物杂交【蓝桥杯】【算法设计与分析】【深度优先搜索】
问题描述:
- 作物杂交是作物栽培中重要的一步。已知有 N 种作物 (编号 1 至 N ),第 i 种作物从播种到成熟的时间为Ti。作物之间两两可以进行杂交,杂交时间取两种中时间较长的一方。如作物 A 种植时间为 5 天,作物 B 种植时间为 7 天,则 AB杂交花费的时间为 7 天。
- 作物杂交会产生固定的作物,新产生的作物仍然属于 N 种作物中的一种。初始时,拥有其中 M 种作物的种子(数量无限,可以支持多次杂交)。同时可以进行多个杂交过程。求问对于给定的目标种子,最少需要多少天能够得到。
解题算法思路:
所求作物T杂交时间应该是杂交时间取两种中时间较长的一方,但是需要种子存在,所以还需要加上2个种子的培养时间。即:
t = Math.max(杂交时间)+Math.max(培养时间)
因为是求最少,所以要遍历所有可能性。通过深度优先遍历所有能够产生T作物的方案,获取其最少的时间。其他具体细节在注释里写的很详细,看代码应该能看懂。
源代码:
1.import java.io.BufferedReader;
2.import java.io.IOException;
3.import java.io.InputStreamReader;
4.import java.io.StreamTokenizer;
5.import java.util.ArrayList;
6.import java.util.Arrays;
7.import java.util.HashMap;
8.
9.public class Crophybridization {// 深度优先搜索
10.
11. static StreamTokenizer re = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
12. static int nextInt() throws IOException {
13. re.nextToken();
14. return (int) re.nval;
15. }
16. static HashMap<Integer, ArrayList<Integer>> map = new HashMap<>();
17.// map<所求作物,arraylist集合>
18.// arraylist集合 存储着 作物1 、作物2、培养时间。
19.// 遍历的时候以3为步长遍历就行。
20. static int[] T;
21. static int[] dp;//dp存储着获取该种子的最小时间 -1代表着未获取 0代表开始就有,获取时间为0
22.
23. public static void main() throws IOException {
24.
25. int n = nextInt();
26. int m = nextInt();
27. int k = nextInt();
28. int t = nextInt();
29.
30. T = new int[n + 1];//i号种子培养时间为T[i]
31. dp = new int[n + 1];
32. Arrays.fill(dp, -1);
33. for (int i = 1; i <= n; i++) {
34. T[i] = nextInt();
35. }
36. for (int i = 0; i < m; i++) {
37. int j = nextInt();
38. dp[j] = 0;
39. }
40. for (int i = 0; i < k; i++) {
41. int a = nextInt();
42. int b = nextInt();
43. int c = nextInt();
44. ArrayList<Integer> value = map.getOrDefault(c, new ArrayList<>());
45. value.add(a);
46. value.add(b);
47. value.add(Math.max(T[a], T[b]));//c通过a b 的杂交时间
48. map.put(c, value);
49. }
50. long ans = dfs(t);
51. System.out.println("得到目标种子的最短杂交时间为"+ans+"天");
52. UI.main();
53. }
54.
55. public static int dfs (int n) { // 获取种子所需要的时间
56. if (dp[n] != -1)
57. return dp[n];
58. ArrayList<Integer> list = map.get(n);
59. int time = Integer.MAX_VALUE;// 遍历所有能够产生T作物的方案,获取其最少的时间
60. for (int i = 0; i < list.size(); i += 3) {
61. Integer n1 = list.get(i);
62. Integer n2 = list.get(i + 1);
63. time = Math.min(time,
64. Math.max(dfs(n2), dfs(n1)) +list.get(i + 2));
65. }
66. dp[n] = time;
67. return time;
68. }
69.}