use std::{
collections::{BinaryHeap, VecDeque},
io::{self, Read},
};
#[derive(Debug)]
struct Stack {
items: VecDeque<usize>,
max: usize,
}
fn main() {
let mut input = String::new();
io::stdin()
.read_to_string(&mut input)
.expect("Failed to read input");
let mut scan = input.split_whitespace();
let mut next_num = || scan.next().unwrap().parse::<usize>().unwrap();
let n = next_num();
let m = next_num();
let k = next_num();
let mut read_stack = || {
let mut items = VecDeque::with_capacity(m);
let mut max = 0;
let mut is_increasing = false;
for i in 0..m {
let item = next_num();
max += item;
if !is_increasing && i > 0 && item > *items.back().unwrap() {
is_increasing = true;
}
items.push_back(item);
}
(Stack { items, max }, is_increasing)
};
let mut inc_stacks = Vec::new();
let mut decr_stacks = Vec::new();
for _ in 0..n {
let (stack, is_increasing) = read_stack();
if is_increasing {
inc_stacks.push(stack);
} else {
decr_stacks.push(stack);
}
}
// 1. ------ Decreasing
let mut heap: BinaryHeap<HeapItem> = BinaryHeap::new();
let mut decreasing_counter = Vec::with_capacity(k + 1);
for pair in decr_stacks.iter_mut().enumerate() {
let index = pair.0;
let stack = pair.1;
heap.push(HeapItem {
index,
value: stack.items.pop_front().unwrap(),
});
}
decreasing_counter.push(0);
let mut sum = 0;
while decreasing_counter.len() <= k && !heap.is_empty() {
let HeapItem { value, index } = heap.pop().unwrap();
sum += value;
decreasing_counter.push(sum);
if let Some(value) = decr_stacks[index].items.pop_front() {
heap.push(HeapItem { index, value });
}
}
let get_decreasing_max = |c: usize| *decreasing_counter.get(c).unwrap_or(&0);
// 2. ------ Increasing
inc_stacks.sort_by_key(|stack| stack.max);
let n_inc = inc_stacks.len();
let mut matrix = vec![vec![0; m]; n_inc];
if n_inc > 0 {
for j in 1..m {
matrix[0][j] = matrix[0][j - 1] + inc_stacks[0].items[j - 1];
}
for i in 1..n_inc {
let stack = &inc_stacks[i];
let mut sum = 0;
for j in 1..m {
sum += stack.items[j - 1];
matrix[i][j] = sum.max(matrix[i - 1][j]);
}
}
}
let mut value = 0;
let mut stacks_sums = Vec::with_capacity(n_inc);
stacks_sums.push(0);
for stack in inc_stacks.into_iter().rev() {
value += stack.max;
stacks_sums.push(value);
}
let get_increasing_max = |c: usize| {
if c == 0 || c > n_inc * m {
return 0;
}
let whole_stacks_value = stacks_sums[c / m];
if c % m == 0 {
return whole_stacks_value;
}
let stacks_count = c / m;
let rest = c % m;
whole_stacks_value + matrix[n_inc - stacks_count - 1][rest]
};
// 3.-------- Solution
let mut result = 0;
for i in 0..=k {
result = result.max(get_increasing_max(i) + get_decreasing_max(k - i));
}
println!("{result}");
}
#[derive(Debug, Eq, PartialEq)]
struct HeapItem {
index: usize,
value: usize,
}
impl Ord for HeapItem {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.value
.cmp(&other.value)
.then_with(|| self.index.cmp(&other.index))
}
}
impl PartialOrd for HeapItem {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | use std::{ collections::{BinaryHeap, VecDeque}, io::{self, Read}, }; #[derive(Debug)] struct Stack { items: VecDeque<usize>, max: usize, } fn main() { let mut input = String::new(); io::stdin() .read_to_string(&mut input) .expect("Failed to read input"); let mut scan = input.split_whitespace(); let mut next_num = || scan.next().unwrap().parse::<usize>().unwrap(); let n = next_num(); let m = next_num(); let k = next_num(); let mut read_stack = || { let mut items = VecDeque::with_capacity(m); let mut max = 0; let mut is_increasing = false; for i in 0..m { let item = next_num(); max += item; if !is_increasing && i > 0 && item > *items.back().unwrap() { is_increasing = true; } items.push_back(item); } (Stack { items, max }, is_increasing) }; let mut inc_stacks = Vec::new(); let mut decr_stacks = Vec::new(); for _ in 0..n { let (stack, is_increasing) = read_stack(); if is_increasing { inc_stacks.push(stack); } else { decr_stacks.push(stack); } } // 1. ------ Decreasing let mut heap: BinaryHeap<HeapItem> = BinaryHeap::new(); let mut decreasing_counter = Vec::with_capacity(k + 1); for pair in decr_stacks.iter_mut().enumerate() { let index = pair.0; let stack = pair.1; heap.push(HeapItem { index, value: stack.items.pop_front().unwrap(), }); } decreasing_counter.push(0); let mut sum = 0; while decreasing_counter.len() <= k && !heap.is_empty() { let HeapItem { value, index } = heap.pop().unwrap(); sum += value; decreasing_counter.push(sum); if let Some(value) = decr_stacks[index].items.pop_front() { heap.push(HeapItem { index, value }); } } let get_decreasing_max = |c: usize| *decreasing_counter.get(c).unwrap_or(&0); // 2. ------ Increasing inc_stacks.sort_by_key(|stack| stack.max); let n_inc = inc_stacks.len(); let mut matrix = vec![vec![0; m]; n_inc]; if n_inc > 0 { for j in 1..m { matrix[0][j] = matrix[0][j - 1] + inc_stacks[0].items[j - 1]; } for i in 1..n_inc { let stack = &inc_stacks[i]; let mut sum = 0; for j in 1..m { sum += stack.items[j - 1]; matrix[i][j] = sum.max(matrix[i - 1][j]); } } } let mut value = 0; let mut stacks_sums = Vec::with_capacity(n_inc); stacks_sums.push(0); for stack in inc_stacks.into_iter().rev() { value += stack.max; stacks_sums.push(value); } let get_increasing_max = |c: usize| { if c == 0 || c > n_inc * m { return 0; } let whole_stacks_value = stacks_sums[c / m]; if c % m == 0 { return whole_stacks_value; } let stacks_count = c / m; let rest = c % m; whole_stacks_value + matrix[n_inc - stacks_count - 1][rest] }; // 3.-------- Solution let mut result = 0; for i in 0..=k { result = result.max(get_increasing_max(i) + get_decreasing_max(k - i)); } println!("{result}"); } #[derive(Debug, Eq, PartialEq)] struct HeapItem { index: usize, value: usize, } impl Ord for HeapItem { fn cmp(&self, other: &Self) -> std::cmp::Ordering { self.value .cmp(&other.value) .then_with(|| self.index.cmp(&other.index)) } } impl PartialOrd for HeapItem { fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> { Some(self.cmp(other)) } } |
English