Skip to content

Commit a039db9

Browse files
committed
Update
1 parent 5928101 commit a039db9

15 files changed

+838
-4
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,5 @@ fabric.properties
7575
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
7676
hs_err_pid*
7777
env.list
78+
79+
.DS_Store

src/sp3/recursion/and/sorting/SegmentedPlots.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import java.util.List;
77

88
/**
9-
* Алла захотела, чтобы у неё под окном были узкие клумбы с тюльпанам.
9+
* Алла захотела, чтобы у неё под окном были узкие клумбы с тюльпанами.
1010
* На схеме земельного участка клумбы обозначаются просто горизонтальными отрезками, лежащими на одной прямой.
1111
* Для ландшафтных работ было нанято n садовников. Каждый из них обрабатывал какой-то отрезок на схеме.
1212
* Процесс был организован не очень хорошо, иногда один и тот же отрезок или его часть могли быть обработаны сразу

src/sp3/recursion/and/sorting/finals/InPlaceQuickSort.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
* Пусть мы как-то выбрали опорный элемент. Заведём два указателя left и right, которые изначально будут указывать
2525
* на левый и правый концы отрезка соответственно. Затем будем двигать левый указатель вправо до тех пор, пока он указывает
2626
* на элемент, меньший опорного. Аналогично двигаем правый указатель влево, пока он стоит на элементе, превосходящем опорный.
27-
* В итоге окажется, что что левее от left все элементы точно принадлежат первой группе, а правее от right — второй.
27+
* В итоге окажется, что левее от left все элементы точно принадлежат первой группе, а правее от right — второй.
2828
* Элементы, на которых стоят указатели, нарушают порядок. Поменяем их местами и продвинем указатели на следующие элементы.
2929
* Будем повторять это действие до тех пор, пока left и right не столкнутся.
3030
*
@@ -46,12 +46,12 @@
4646
* `r` движется влево пока элемент, на который он указывает, больше `pivot`. Когда оба указателя останавливаются, они
4747
* указывают на элементы, находящиеся не на своих местах. Элементы переставляются. Таким образом получаем, что все элементы,
4848
* левее `r` меньше `pivot`, а все элементы правее `l` – больше. Рекурсивно повторяем вышеописанные действия для левой и правой
49-
* частей инвервала.
49+
* частей интервала.
5050
*
5151
* -- ДОКАЗАТЕЛЬСТВО КОРРЕКТНОСТИ --
5252
* На каждом уровне рекурсии слева оказываются элементы, меньшие некоторого числа из интервала, а справа – большие.
5353
* Рекурсивные вызовы продолжаются, пока не будет получен пустой массив или массив из одного элемента,
54-
* которые по определению являются отстортированными. Поскольку все перестановки совершаются in-place в исходном массиве,
54+
* которые по определению являются отсортированными. Поскольку все перестановки совершаются in-place в исходном массиве,
5555
* то весь массив – отсортированный.
5656
*
5757
* -- ВРЕМЕННАЯ СЛОЖНОСТЬ --
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package sp7.greedy.and.dynamic;
2+
3+
import java.io.*;
4+
import java.util.Arrays;
5+
import java.util.List;
6+
7+
import static java.util.stream.Collectors.toList;
8+
9+
/**
10+
* Тимофей пошёл снять деньги в банкомат. Ему нужно m франков. В банкомате в бесконечном количестве имеются купюры
11+
* различных достоинств. Всего различных достоинств n. Купюр каждого достоинства можно взять бесконечно много.
12+
* Нужно определить число способов, которыми Тимофей сможет набрать нужную сумму.
13+
*
14+
* В первой строке записано целое число m — сумма, которую нужно набрать. Во второй строке n — количество монет в банкомате.
15+
* Оба числа не превосходят 300. Далее в третьей строке записано n уникальных натуральных чисел,
16+
* каждое в диапазоне от 1 до 1000 –– достоинства купюр.
17+
*
18+
* Нужно вывести число способов, которым Тимофей сможет набрать нужную сумму.
19+
*/
20+
public class CashMachine {
21+
22+
private static long count(int amount, List<Integer> coins) {
23+
if (amount < 1) return 0;
24+
25+
long[] memo = new long[amount + 1];
26+
memo[0] = 1;
27+
28+
for (int coin : coins) {
29+
for (int currentAmount = coin; currentAmount <= amount; currentAmount++) {
30+
int prev = currentAmount - coin;
31+
memo[currentAmount] += memo[prev];
32+
}
33+
}
34+
35+
return memo[amount];
36+
}
37+
38+
public static void main(String[] args) throws IOException {
39+
try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
40+
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out))) {
41+
int amount = readInt(reader);
42+
int n = readInt(reader);
43+
List<Integer> coins = Arrays.stream(reader.readLine().split(" "))
44+
.map(Integer::parseInt)
45+
.collect(toList());
46+
47+
long count = count(amount, coins);
48+
System.out.println(count);
49+
}
50+
}
51+
52+
private static int readInt(BufferedReader reader) throws IOException {
53+
return Integer.parseInt(reader.readLine());
54+
}
55+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package sp7.greedy.and.dynamic;
2+
3+
import java.io.*;
4+
import java.util.Arrays;
5+
import java.util.HashMap;
6+
import java.util.List;
7+
import java.util.Map;
8+
9+
import static java.util.stream.Collectors.toList;
10+
11+
/**
12+
* Алла хочет купить дом на Алгосах. Для этого ей надо много наличных, которые она собирается получить в банкомате.
13+
* Банкомат приличный, поэтому в нём есть бесконечно много банкнот каждого номинала.
14+
* Всего номиналов k штук. Дом мечты Аллы стоит x франков.
15+
* Найдите минимальное количество банкнот, которые в сумме дадут x франков. Если в набор входит несколько банкнот
16+
* одинакового номинала, то учитывать надо их все.
17+
* Например, если необходимо набрать 15 франков, а в банкомате купюры по 5 франков, то минимальное число купюр —- 3.
18+
*
19+
* В первой строке дана сумма, которую хочет получить Алла –— натуральное число x (1 ≤ x ≤ 10^4).
20+
* Во второй строке дано число различных номиналов k. В третьей строке даны k чисел (1 ≤ k ≤ 1000) —– номиналы купюр.
21+
* Все номиналы лежат в диапазоне от 1 до 10^4. Номиналы купюр могут повторяться.
22+
*
23+
* Выведите единственное число —– минимальное количество купюр, которыми можно набрать x франков.
24+
* Если нельзя набрать в точности x франков, то выведите -1.
25+
*/
26+
public class CoinChange {
27+
28+
private static int minCoinsNumber(int amount, List<Integer> coins) {
29+
if (amount < 1) return 0;
30+
31+
Map<Integer, Integer> memo = new HashMap<>();
32+
memo.put(0, 0);
33+
34+
for (int i = 1; i <= amount; i++) {
35+
int count = Integer.MAX_VALUE;
36+
for (int coin : coins) {
37+
if (i - coin < 0) continue;
38+
39+
Integer prev = memo.get(i - coin);
40+
if (prev != null) {
41+
count = Math.min(count, prev + 1);
42+
}
43+
}
44+
45+
if (count != Integer.MAX_VALUE) {
46+
memo.put(i, count);
47+
}
48+
}
49+
50+
return memo.getOrDefault(amount, -1);
51+
}
52+
53+
54+
55+
public static void main(String[] args) throws IOException {
56+
try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
57+
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out))) {
58+
int amount = readInt(reader);
59+
int n = readInt(reader);
60+
List<Integer> coins = Arrays.stream(reader.readLine().split(" "))
61+
.map(Integer::parseInt)
62+
.collect(toList());
63+
64+
int min = minCoinsNumber(amount, coins);
65+
System.out.println(min);
66+
}
67+
}
68+
69+
private static int readInt(BufferedReader reader) throws IOException {
70+
return Integer.parseInt(reader.readLine());
71+
}
72+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package sp7.greedy.and.dynamic;
2+
3+
import java.io.*;
4+
5+
/**
6+
* Черепаха Кондратина путешествует по клетчатому полю из n строк и m столбцов.
7+
* В каждой клетке либо растёт цветочек, либо не растёт. Кондратине надо добраться из левого нижнего
8+
* в правый верхний угол и собрать как можно больше цветочков.
9+
* Помогите ей с этой сложной задачей и определите, какое наибольшее число цветочков она сможет собрать при условии,
10+
* что Кондратина умеет передвигаться только на одну клетку вверх или на одну клетку вправо за ход.
11+
*
12+
* В первой строке даны размеры поля n и m (через пробел). Оба числа лежат в диапазоне от 1 до 1000.
13+
* В следующих n строках задано поле. Каждая строка состоит из m символов 0 или 1, записанных подряд без пробелов,
14+
* и завершается переводом строки. Если в клетке записана единица, то в ней растёт цветочек.
15+
*
16+
* Выведите единственное число — максимальное количество цветочков, которое сможет собрать Кондратина.
17+
*/
18+
public class CollectingFlowers {
19+
20+
private static int collect(int[][] field) {
21+
int[][] memo = new int[field.length][field[0].length];
22+
23+
for (int i = field.length - 1; i >= 0; i--) {
24+
for (int j = 0; j < field[0].length; j++) {
25+
int left = j - 1 >= 0 ? memo[i][j - 1] : 0;
26+
int bottom = i + 1 < memo.length ? memo[i + 1][j] : 0;
27+
28+
memo[i][j] = field[i][j] + Math.max(left, bottom);
29+
}
30+
}
31+
32+
return memo[0][field[0].length - 1];
33+
}
34+
35+
public static void main(String[] args) throws IOException {
36+
try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
37+
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out))) {
38+
String[] s = reader.readLine().split(" ");
39+
int n = Integer.parseInt(s[0]);
40+
int m = Integer.parseInt(s[1]);
41+
42+
int[][] field = new int[n][m];
43+
for (int i = 0; i < n; i++) {
44+
String line = reader.readLine();
45+
for (int c = 0; c < line.length(); c++) {
46+
field[i][c] = Character.getNumericValue(line.charAt(c));
47+
}
48+
}
49+
50+
int flowers = collect(field);
51+
System.out.println(flowers);
52+
}
53+
}
54+
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package sp7.greedy.and.dynamic;
2+
3+
import java.io.*;
4+
import java.util.Deque;
5+
import java.util.LinkedList;
6+
7+
/**
8+
* Теперь черепашке Кондратине надо узнать не только, сколько цветочков она может собрать,
9+
* но и как ей построить свой маршрут для этого. Помогите ей!
10+
* Напомним, что Кондратине надо дойти от левого нижнего до правого верхнего угла,
11+
* а передвигаться она умеет только вверх и вправо.
12+
*
13+
* В первой строке даны размеры поля n и m (через пробел). Оба числа лежат в диапазоне от 1 до 1000.
14+
* В следующих n строках задано поле. Каждая строка состоит из m символов 0 или 1 и завершается переводом строки.
15+
* Если в клетке записана единица, то в ней растет цветочек.
16+
*
17+
* Выведите в первой строке максимальное количество цветочков, которое сможет собрать Кондратина.
18+
* Во второй строке выведите маршрут в виде последовательности символов «U» и «R»,
19+
* где «U» означает передвижение вверх, а «R» – передвижение вправо.
20+
* Если возможных оптимальных путей несколько, то выведите любой.
21+
*/
22+
public class CollectingFlowersWithPath {
23+
24+
private static Deque<Character> path(int[][] memo) {
25+
Deque<Character> path = new LinkedList<>();
26+
27+
int i = 0;
28+
int j = memo[0].length - 1;
29+
while (i < memo.length && j >= 0) {
30+
int left = j - 1 >= 0 ? memo[i][j - 1] : -1;
31+
int bottom = i + 1 < memo.length ? memo[i + 1][j] : -1;
32+
33+
if (left == -1 && bottom == -1) break;
34+
35+
if (left == -1 || left < bottom) {
36+
path.push('U');
37+
i += 1;
38+
} else {
39+
path.push('R');
40+
j -= 1;
41+
}
42+
}
43+
44+
return path;
45+
}
46+
47+
private static int[][] count(int[][] field) {
48+
int[][] memo = new int[field.length][field[0].length];
49+
50+
for (int i = field.length - 1; i >= 0; i--) {
51+
for (int j = 0; j < field[0].length; j++) {
52+
int left = j - 1 >= 0 ? memo[i][j - 1] : 0;
53+
int bottom = i + 1 < memo.length ? memo[i + 1][j] : 0;
54+
55+
memo[i][j] = field[i][j] + Math.max(left, bottom);
56+
}
57+
}
58+
59+
return memo;
60+
}
61+
62+
public static void main(String[] args) throws IOException {
63+
try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
64+
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out))) {
65+
String[] s = reader.readLine().split(" ");
66+
int n = Integer.parseInt(s[0]);
67+
int m = Integer.parseInt(s[1]);
68+
69+
int[][] field = new int[n][m];
70+
for (int i = 0; i < n; i++) {
71+
String line = reader.readLine();
72+
for (int c = 0; c < line.length(); c++) {
73+
field[i][c] = Character.getNumericValue(line.charAt(c));
74+
}
75+
}
76+
77+
int[][] count = count(field);
78+
Deque<Character> path = path(count);
79+
80+
System.out.println(count[0][field[0].length - 1]);
81+
while (!path.isEmpty()) {
82+
writer.write(path.pop());
83+
}
84+
}
85+
}
86+
}

0 commit comments

Comments
 (0)