diff --git a/algorithm/com/shiyu/Main.java b/algorithm/com/shiyu/Main.java index 948d064198f9fbf13bd9e03e8f19c856bc5a3f4d..b12c0aa6fd2499a6b238ed8bdcdd809ab64e9914 100644 --- a/algorithm/com/shiyu/Main.java +++ b/algorithm/com/shiyu/Main.java @@ -1,28 +1,60 @@ package com.shiyu; -import java.util.PriorityQueue; -import java.util.Scanner; +import java.util.*; public class Main { + private static class Node implements Comparable { + public int Juli; + public int You = 0; + + public Node(int juli) { + Juli = juli; + } + + @Override + public int compareTo(Node node) { + return this.Juli - node.Juli; + } + } + public static void main(String[] args) { Scanner sc = new Scanner(System.in); - int n = sc.nextInt(); - PriorityQueue pq = new PriorityQueue(); - for (int i = 0; i < n; i++) { - int a = sc.nextInt(); - pq.add(a); + int N = sc.nextInt();//几个加油站 + Node[] node = new Node[N + 1]; + for (int i = 0; i < N; i++) { + node[i] = new Node(sc.nextInt()); + node[i].You = sc.nextInt(); + } + int L = sc.nextInt(); + int P = sc.nextInt(); + for (int i = 0; i < N; i++) { + node[i].Juli = L - node[i].Juli;//更改为加油站距离起点的位置 } - long ans = 0; - int c = 0; - if (pq.size() == 1) - ans += pq.poll(); - while (pq.size() > 1) { - Integer p1 = pq.poll(); - Integer p2 = pq.poll(); - c = p1 + p2; - ans += c; - pq.add(c); + node[N] = new Node(L); + Arrays.sort(node); + PriorityQueue pq = new PriorityQueue(N + 10, new Comparator() { + @Override + public int compare(Integer t1, Integer t2) { + return t2 - t1; + } + }); + int res = 0;//加油次数 + int pos = 0;//当前所在位置 + int tank = P;//油箱剩的油的数量 + for (int i = 0; i <= N; i++) {//把终点看做加油站,看能不能到这个加油站 + int d = node[i].Juli - pos;//卡车的位置从0开始,到达第i个加油站需要多少油 + while (tank - d < 0) {//如果无法到达第i个加油站 + if (pq.size() == 0)//从优先队列里面没有加油站,没有刻 + System.out.println("-1"); + tank += pq.poll(); + res++; + } + tank -= d;//减去走到第i个加油站需要的油,区间是什么呢, + // 第一次区间(0,A[i])需要这么多油,第二次及以后区间(A[i-1],A[i]) + // 每次都要维护油的数量,区间消耗的油 + pos = node[i].Juli;//卡车开到第i个加油站 + pq.offer(node[i].You);//每到一个加油站,就把能加的油加进优先队列 } - System.out.println(ans); + System.out.println(res); } -} \ No newline at end of file +} diff --git a/algorithm/com/shiyu/tsdt.java b/algorithm/com/shiyu/tsdt.java index 1ed90ce49673f6803f5cbfecd6753317fc425767..4df40270c39401c4e9fe2ed2e478c64408461d4e 100644 --- a/algorithm/com/shiyu/tsdt.java +++ b/algorithm/com/shiyu/tsdt.java @@ -1,25 +1,8 @@ package com.shiyu; -import java.util.Arrays; - public class tsdt { public static void main(String[] args) { -// System.out.println(isPalindrome(121)); -// PriorityQueue a = new PriorityQueue(); -// -// a.add(6); -// a.add(5); -// -// System.out.println(a.poll()); - int d = 2 & 3; - System.out.println(d); - int[] arr = {3, 4, 6, 87, 478}; - System.out.println(Arrays.binarySearch(arr, 0, 2, 4)); - } - public static boolean isPalindrome(int x) { - return new StringBuilder(x + "").reverse().toString().equals(Integer.toString(x)); - } } diff --git a/algorithm/dp/bag.java b/algorithm/dp/bag.java index 93432fec7b2bf3698436377e1357b73ae6cfb28d..62dc79a5ba85170b17afd37e3280f077e7e3714d 100644 --- a/algorithm/dp/bag.java +++ b/algorithm/dp/bag.java @@ -116,7 +116,7 @@ public class bag { dp[i + 1][j] = Math.min(dp[i][j], dp[i][j - v[i]] == Integer.MAX_VALUE ? dp[i][j] : dp[i][j - v[i]] + w[i]); - //非常重要由于初始化为Integer.MAX_VALUE,再加上重量会溢出为 + //非常重要由于初始化为Integer.MAX_VALUE,再加上重量会溢出为负数,导致错误 //dp[i][j - v[i]] + w[i] } } diff --git "a/algorithm/\345\210\206\346\262\273.markdown" "b/algorithm/\345\210\206\346\262\273.markdown" index b5401e102f8bce1db17a8af77e36b7a2455b74f4..43264c99e8c0d2835a3998348649c0a38f938e95 100644 --- "a/algorithm/\345\210\206\346\262\273.markdown" +++ "b/algorithm/\345\210\206\346\262\273.markdown" @@ -1,4 +1,4 @@ -###分治法 + ###分治法 ``` 将原问题划分,成若干个,规模较小而结构与问题一致的子问题 递归地解决这些子问题,然后再合并其结果,就能得到原问题的解 diff --git "a/\346\214\221\346\210\230\347\250\213\345\272\217\350\256\276\350\256\241\347\253\236\350\265\233/src/Greedy/\345\210\207\346\234\250\346\235\277.java" "b/\346\214\221\346\210\230\347\250\213\345\272\217\350\256\276\350\256\241\347\253\236\350\265\233/src/Greedy/\345\210\207\346\234\250\346\235\277.java" index eff991bf9240ea99cdda62f669f5c9b9f8d9b463..ef81ff47cf4018909bed3c066a0186639452a018 100644 --- "a/\346\214\221\346\210\230\347\250\213\345\272\217\350\256\276\350\256\241\347\253\236\350\265\233/src/Greedy/\345\210\207\346\234\250\346\235\277.java" +++ "b/\346\214\221\346\210\230\347\250\213\345\272\217\350\256\276\350\256\241\347\253\236\350\265\233/src/Greedy/\345\210\207\346\234\250\346\235\277.java" @@ -1,6 +1,7 @@ package Greedy; import java.util.PriorityQueue; +import java.util.Scanner; /** * POJ 3253 @@ -20,7 +21,7 @@ import java.util.PriorityQueue; * N=3, L={8, 5, 8} * 输出样例: * 34 - * ,要使总费用最小,那么每次只选取最小长度的两块木板相加,再把这些“和”累加到总费用中即可 + * ,要使总费用最小,那么每次只选取最小长度的两块木板相加,再把这些“和”累加到总费用中即可 * 本题虽然利用了Huffman思想,但是直接用HuffmanTree做会超时,可以用优先队列做 * 因为朴素的HuffmanTree思想是: * (1)先把输入的所有元素升序排序,再选取最小的两个元素,把他们的和值累加到总费用 @@ -28,8 +29,8 @@ import java.util.PriorityQueue; * 则累计的费用就是最小费用 */ public class 切木板 { - public static void main(String[] args) { - int[] arr = {8, 5, 8, 4, 3}; + public static void main(String[] args) { + int[] arr = {8, 5, 8}; System.out.println(Zui(3, arr)); } @@ -39,15 +40,43 @@ public class 切木板 { pq.add(arr[i]); } int ans = 0; + Integer p1, p2, p3; + while (pq.size() > 1) { + p1 = pq.poll(); + p2 = pq.poll(); + p3 = p1 + p2; + ans += p3; + pq.add(p3); + } + return ans; + } + + /** + * POJ 3253题解 + */ + public static void Tijie() { + Scanner sc = new Scanner(System.in); + int n = sc.nextInt(); + PriorityQueue pq = new PriorityQueue(); + for (int i = 0; i < n; i++) { + int a = sc.nextInt(); + pq.add(a); + } + long ans = 0; + int c = 0; + if (pq.size() == 1) + ans += pq.poll(); while (pq.size() > 1) { Integer p1 = pq.poll(); Integer p2 = pq.poll(); - ans += p1 + p2; - pq.add(p1 + p2); + c = p1 + p2; + ans += c; + pq.add(c); } - return ans; + System.out.println(ans); } } + /** * #include * #include diff --git "a/\346\214\221\346\210\230\347\250\213\345\272\217\350\256\276\350\256\241\347\253\236\350\265\233/src/PriorityQueue/\345\215\241\350\275\246\345\212\240\346\262\271.java" "b/\346\214\221\346\210\230\347\250\213\345\272\217\350\256\276\350\256\241\347\253\236\350\265\233/src/PriorityQueue/\345\215\241\350\275\246\345\212\240\346\262\271.java" new file mode 100644 index 0000000000000000000000000000000000000000..48ec60feb9463c86d6c845fc41c8d72313ff120b --- /dev/null +++ "b/\346\214\221\346\210\230\347\250\213\345\272\217\350\256\276\350\256\241\347\253\236\350\265\233/src/PriorityQueue/\345\215\241\350\275\246\345\212\240\346\262\271.java" @@ -0,0 +1,124 @@ +package PriorityQueue; + +import java.util.Arrays; +import java.util.Comparator; +import java.util.PriorityQueue; +import java.util.Scanner; + +/** + * POJ 2431 + * 题目大意:一辆卡车,初始时,距离终点L,油量为P, + * 在起点到终点途中有N个加油站,每个加油站油量有限, + * 而卡车的油箱容量无限,卡车在行车途中, + * 每走一个单位的距离消耗一个单位的油量, + * 给定n个加油站距离起点的距离以及油存储量。 + * A数组代表距离起点 + * B数组代表每个加油站最多加多少油 + * 假设油箱容量无限大 + * 问卡车是否能到达终点,如果可达,最少需要加多少次油,否则输出-1. + * 1≤N≤10000 + * 输入: + * N=4 L=25 P=10 + * A={10,14,20,21} + * B={10,5,2,4} + * 输出: + * 2(在第一个和第二个加油站加油) + */ +public class 卡车加油 { + public static void main(String[] args) { + int N = 4, L = 25, P = 10; + int[] A = {10, 14, 20, 21}; + int[] B = {10, 5, 2, 4}; + System.out.println(Kache(N, L, P, A, B)); + } + + public static int Kache(int N, int L, int P, int[] A, int[] B) { + A = Arrays.copyOf(A, A.length + 1); + B = Arrays.copyOf(B, B.length + 1); + A[N] = L;//把终点也设为加油站 + B[N] = 0;//只能加0的油 + System.out.println(Arrays.toString(A)); + PriorityQueue pq = new PriorityQueue(10005, new Comparator() { + @Override + public int compare(Integer t1, Integer t2) { + return t2 - t1; + } + }); + int res = 0;//加油次数 + int pos = 0;//当前所在位置 + int tank = P;//油箱剩的油的数量 + for (int i = 0; i <= N; i++) {//把终点看做加油站,看能不能到这个加油站 + int d = A[i] - pos;//卡车的位置从0开始,到达第i个加油站需要多少油 + while (tank - d < 0) {//如果无法到达第i个加油站 + if (pq.size() == 0)//从优先队列里面没有加油站,没有刻 + return -1;//无法到达 + tank += pq.poll(); + res++; + } + tank -= d;//减去走到第i个加油站需要的油,区间是什么呢, + // 第一次区间(0,A[i])需要这么多油,第二次及以后区间(A[i-1],A[i]) + // 每次都要维护油的数量,区间消耗的油 + pos = A[i];//卡车开到第i个加油站 + pq.offer(B[i]);//每到一个加油站,就把能加的油加进优先队列 + } + return res; + } + + private static class Node implements Comparable { + public int Juli; + public int You = 0; + + public Node(int juli) { + Juli = juli; + } + + @Override + public int compareTo(Node node) { + return this.Juli - node.Juli; + } + } + + /** + * POJ 2431 题解通过 + */ + public static void Tijie() { + Scanner sc = new Scanner(System.in); + int N = sc.nextInt();//几个加油站 + Node[] node = new Node[N + 1]; + for (int i = 0; i < N; i++) { + node[i] = new Node(sc.nextInt()); + node[i].You = sc.nextInt(); + } + int L = sc.nextInt(); + int P = sc.nextInt(); + for (int i = 0; i < N; i++) { + node[i].Juli = L - node[i].Juli;//更改为加油站距离起点的位置 + } + node[N] = new Node(L); + Arrays.sort(node); + PriorityQueue pq = new PriorityQueue(N + 10, new Comparator() { + @Override + public int compare(Integer t1, Integer t2) { + return t2 - t1; + } + }); + int res = 0;//加油次数 + int pos = 0;//当前所在位置 + int tank = P;//油箱剩的油的数量 + for (int i = 0; i <= N; i++) {//把终点看做加油站,看能不能到这个加油站 + int d = node[i].Juli - pos;//卡车的位置从0开始,到达第i个加油站需要多少油 + while (tank - d < 0) {//如果无法到达第i个加油站 + if (pq.size() == 0)//从优先队列里面没有加油站,没有刻 + System.out.println("-1"); + tank += pq.poll(); + res++; + } + tank -= d;//减去走到第i个加油站需要的油,区间是什么呢, + // 第一次区间(0,A[i])需要这么多油,第二次及以后区间(A[i-1],A[i]) + // 每次都要维护油的数量,区间消耗的油 + pos = node[i].Juli;//卡车开到第i个加油站 + pq.offer(node[i].You);//每到一个加油站,就把能加的油加进优先队列 + } + System.out.println(res); + } +} diff --git "a/\346\214\221\346\210\230\347\250\213\345\272\217\350\256\276\350\256\241\347\253\236\350\265\233/src/dp/\345\210\222\345\210\206\346\225\260.java" "b/\346\214\221\346\210\230\347\250\213\345\272\217\350\256\276\350\256\241\347\253\236\350\265\233/src/dp/\345\210\222\345\210\206\346\225\260.java" new file mode 100644 index 0000000000000000000000000000000000000000..004ece138b72ea4687ba18b2d09e7574ced3abfb --- /dev/null +++ "b/\346\214\221\346\210\230\347\250\213\345\272\217\350\256\276\350\256\241\347\253\236\350\265\233/src/dp/\345\210\222\345\210\206\346\225\260.java" @@ -0,0 +1,37 @@ +package dp; + +/** + * 有n个无区别的物品,将它们划分成不超过m组, + * 求出划分方法数模M的余数 + *

+ * 1≤m≤n≤1000 + * 2≤M≤10000 + *

+ * 输入示例: + * n=4 + * m=3 + * M=10000 + * 输出: + * 4(1+1+2=1+3=2+2) + */ +public class 划分数 { + public static void main(String[] args) { + HuaFen(4, 3, 10000); + } + + public static int HuaFen(int n, int m, int M) { + int[][] dp = new int[m + 1][n + 1]; + dp[0][0] = 1; + for (int i = 1; i <= m; i++) { + for (int j = 0; j <= n; j++) { + if (j - i >= 0) { + dp[i][j] = (dp[i - 1][j] + dp[i][j - i]) % M; + } else { + dp[i][j] = dp[i - 1][j]; + } + } + } + System.out.println(dp[m][n]); + return dp[m][n]; + } +} diff --git "a/\346\214\221\346\210\230\347\250\213\345\272\217\350\256\276\350\256\241\347\253\236\350\265\233/src/dp/\345\244\232\351\207\215\351\203\250\345\210\206\345\222\214.java" "b/\346\214\221\346\210\230\347\250\213\345\272\217\350\256\276\350\256\241\347\253\236\350\265\233/src/dp/\345\244\232\351\207\215\351\203\250\345\210\206\345\222\214.java" index b1603715f82bf4b170162dfa8156870e0a8284ee..b66bd3f501f37c6a9742dd3a709cef4249c7ede0 100644 --- "a/\346\214\221\346\210\230\347\250\213\345\272\217\350\256\276\350\256\241\347\253\236\350\265\233/src/dp/\345\244\232\351\207\215\351\203\250\345\210\206\345\222\214.java" +++ "b/\346\214\221\346\210\230\347\250\213\345\272\217\350\256\276\350\256\241\347\253\236\350\265\233/src/dp/\345\244\232\351\207\215\351\203\250\345\210\206\345\222\214.java" @@ -53,5 +53,4 @@ public class 多重部分和 { } return dp[K]; } - } diff --git "a/\346\214\221\346\210\230\347\250\213\345\272\217\350\256\276\350\256\241\347\253\236\350\265\233/src/dp/\345\244\232\351\207\215\351\233\206\347\273\204\345\220\210\346\225\260.java" "b/\346\214\221\346\210\230\347\250\213\345\272\217\350\256\276\350\256\241\347\253\236\350\265\233/src/dp/\345\244\232\351\207\215\351\233\206\347\273\204\345\220\210\346\225\260.java" new file mode 100644 index 0000000000000000000000000000000000000000..e0c1b80a3a6e315ed2d51ae3bc3f065c26242d11 --- /dev/null +++ "b/\346\214\221\346\210\230\347\250\213\345\272\217\350\256\276\350\256\241\347\253\236\350\265\233/src/dp/\345\244\232\351\207\215\351\233\206\347\273\204\345\220\210\346\225\260.java" @@ -0,0 +1,20 @@ +package dp; + +/** + * 有n种物品,第i种物品有ai个,不同种类的物品可以互相区分, + * 但相同种类的无法区分,从中取出m个,有多少种取法, + * 求出方案数量模M的余数 + * 1≤n≤1000 + * 1≤m≤1000 + * 1≤ai≤1000 + * 2≤M≤10000 + */ +public class 多重集组合数 { + public static void main(String[] args) { + + } + + public static int Duo(int n, int m, int[] a, int M) { + return 0; + } +}