Here is the link to the contest. The problems are from Codeforces' problemset.
A. Naod and Colors
For positions whose numbers are the same, they cannot be colored using the same color.
Let us color the $$$i$$$-th occurrence of any number using color $$$i$$$.
- We can see that:
- We cannot use fewer colors: if there are $$$k$$$ occurrences of any number, at least $$$k$$$ color is needed.
- The assignment of color is valid: Since the sequence was non-increasing, for any subsequence it is also non-increasing. As there are no duplicates in colored subsequence, the subsequence is strictly increasing as well.
Therefore, we only need to count the number of occurrences of every number and take the maximum of them.
import sys
from collections import Counter
input = lambda: sys.stdin.readline().rstrip()
t = int(input())
for _ in range(t):
n = int(input())
a = list(map(int, input().split()))
count = Counter(a)
print(max(count.values()))
B. Project Phase Closing
To calculate the lane and desk where eulmelk can sit, we can use the remainder theorem in division with a little bit modification. To find the side(either $$$L$$$ or $$$R$$$) where eulmelk can sit, the parity of the input variable $$$k$$$ can easily tell us.
n, m, k = map(int, input().split())
r = (k - 1) // (2 * m) + 1
d = (k - 1) % (2 * m) // 2 + 1
loc = 'R' if k % 2 == 0 else 'L'
print(r, d, loc)
C. Coins
To solve this problem, we can use dynamic programming (DP) to find the minimum number of 1-burle coins required. This problem is a simpler version of the coin change problem with only 3 coin denominations: 1, 3, and 5 burles.
Dynamic Programming Approach:
- Define the DP State:
- Let
dp[i]
represent the minimum number of 1-burle coins needed to make the amounti
.
- State Transition:
- To compute
dp[i]
, consider the following transitions:- When using a 1-burle coin:
markdown dp[i] = min(dp[i], dp[i - 1] + 1)
- When using a 3-burle coin:
markdown dp[i] = min(dp[i], dp[i - 3])
- When using a 5-burle coin:
markdown dp[i] = min(dp[i], dp[i - 5])
- When using a 1-burle coin:
The above transitions ensure that for each amount i
, dp[i]
is updated to reflect the minimum number of 1-burle coins required by considering the use of 1-burle, 3-burle, and 5-burle coins.
- Initialization:
- Initialize
dp[0]
to0
because no 1-burle coins are needed to make an amount of0
. - Initialize all other entries in
dp
to a large value (e.g., infinity) to represent that those amounts are initially unreachable.
- Algorithm:
- Iterate through all amounts from
1
to the desired amount and updatedp[i]
using the state transitions described.
By following this approach, you can efficiently determine the minimum number of 1-burle coins needed to make any given amount using coins of denominations 1, 3, and 5 burles.
dp = [float('inf')] * 101
dp[0] = 0
for i in range(1, len(dp)):
if i-1 >= 0:
dp[i] = min(dp[i], dp[i-1] + 1)
if i-3 >= 0:
dp[i] = min(dp[i], dp[i-3])
if i-5 >= 0:
dp[i] = min(dp[i], dp[i-5])
for _ in range(int(input())):
print(dp[int(input())])
D. Vacation
There are two key observations to this problem
- after each pair of moves, the directions go back to the original ones;
- after each move, we can immediately go back (and combining these observations, we can derive that if we go from city $$$i$$$ to some other city $$$j$$$, we can always go back).
So our task is to find the leftmost and the rightmost city reachable from each city. To calculate for the left side, the movement should start with $$$'L'$$$, and to go beyond that, it should alternate. Similarly, for the right side, the first move should be $$$'R'$$$, and to go beyond that, it should alternate. We can calculate the number of reachable cities using prefix and suffix arrays
import sys
def solve():
n = int(sys.stdin.readline().strip())
s = sys.stdin.readline().strip()
pref = [1] * n
for i in range(1, n):
if s[i] != s[i - 1]:
pref[i] = pref[i -1] + 1
suff = [1] * n
for i in range(n -2, -1, -1):
if s[i] != s[i + 1]:
suff[i] = suff[i + 1] + 1
ans = [1]* (n + 1)
if s[0] == "R":
ans[0] += suff[0]
for i in range(1, n):
if s[i] == "R":
ans[i] += suff[i]
if s[i - 1] == "L":
ans[i] += pref[i - 1]
if s[-1] == "L":
ans[-1] += pref[-1]
print(*ans)
t = int(sys.stdin.readline().strip())
for _ in range(t):
solve()
E. A2SV
Note that the problem basically states the following: you are given a rooted tree; you can pair two vertices $$$x$$$ and $$$y$$$ if neither $$$x$$$ is an ancestor of $$$y$$$ nor $$$y$$$ is an ancestor of $$$x$$$.
. Each vertex can be used in at most one pair. Calculate the maximum possible number of pairs you can make.
Let's look at subtrees of child nodes of the root. If two vertices belong to different subtrees, we can pair them up. So we can slightly rephrase the problem: given m types of objects, with counts $$$sz_1,sz_2,…,sz_m$$$
, find the maximum number of pairs that can be formed using objects of different types.
This is a well-known problem with the following solution. Let tot be the total number of objects and $$$mx$$$ be the type that has the maximum number of objects (maximum value of $$$sz$$$). If the number of objects of type $$$mx$$$ is at most the number of all other objects (i. e. $$$sz_{mx}$$$ ≤ $$$tot − sz_{mx}$$$), then we can pair all objects (except $$$1$$$ if the total number of objects is odd). Otherwise, we can create $$$tot−sz_{mx}$$$ pairs of the form $$$(mx,i)$$$ for all $$$i$$$ except $$$mx$$$.
.
Now we can return to the original problem. If the first aforementioned option is met for the root, then we know the answer to the problem is tot2 . Otherwise, we can create $$$tot − sz_{mx}$$$ pairs, but some nodes from the $$$mx$$$-th child's subtree are left unmatched (there are not enough vertices outside that subtree). So we can recursively look at the mx-th child subtree and solve the same problem. The only difference is that some number of vertices from that subtree are already matched. To solve this issue, we can add the parameter k — how many vertices in the current subtree are already matched (we care only about the number of them). From the second paragraph, we know that the best situation (we can pair all objects) appears when the maximum value is at most the number of all other objects. Using this fact, we can say that k matched vertices belong to the $$$mx$$$-th child's subtree. So we have to modify our check formula from $$$sz_{mx}$$$ ≤ $$$tot−sz_{mx}$$$ to $$$sz_{mx} − k$$$ ≤ $$$tot − sz_{mx}$$$.
. This process goes on until the current vertex (subtree) is a leaf or the condition is met.
This solution works in $$$O(n)$$$. if we precalculate the sizes for all the subtrees with a DFS before running it.
from collections import defaultdict, deque
def solve():
n = int(input())
a = list(map(int, input().split()))
d = defaultdict(list)
for i in range(n - 1):
d[i + 2].append(a[i])
d[a[i]].append(i + 2)
queue = deque([(1, 1)])
level = [0] * (n + 1)
v = [0] * (n + 1)
while queue:
x, y = queue.popleft()
level[y] += 1
v[x] = 1
for i in d[x]:
if v[i] == 0:
queue.append((i, y + 1))
ans = 0
unpaired = 0
for i in range(n, 1, -1):
if level[i] > 1:
x = min(unpaired, level[i] - 1)
ans += x
unpaired -= x
level[i] -= x
ans += level[i] // 2
unpaired += level[i] % 2
print(ans)
t = int(input())
for _ in range(t):
solve()