D - 花壇の花選び / Choosing Flowers for the Flower Bed 解説 by admin
Claude 4.6 Opus (Thinking)Overview
Given \(N\) types of flowers (\(N \leq 15\)), select at most \(K\) types to maximize the sum of flower beauty values and contest prize money. Since \(N\) is small, we can enumerate all possible flower selections (bit brute force) to solve the problem.
Analysis
Key Observation
- The constraint \(N \leq 15\) is very small. Since there are \(2\) choices (select or not select) for each of the \(N\) types of flowers, the total number of combinations is only \(2^{15} = 32768\).
- For each combination, we just need to calculate the total beauty and total contest prize money, so full enumeration is well within time limits.
Contest Participation Check
The condition for participating in contest \(j\) (= being required to participate) is “having planted at least \(1\) type of flower with a number between \(L_j\) and \(R_j\) inclusive.”
For example, if \(L_j = 2, R_j = 4\), the participation condition is satisfied if any one of flowers \(2, 3, 4\) is selected.
We perform this check efficiently using bitmasks. We map flower \(i\) (\(1\)-indexed) to bit \(i-1\), and for contest \(j\), we precompute a mask contest_mask[j] with bits set from \(L_j\) to \(R_j\). By taking the AND of the selected flower set flower_set with this mask, we can determine the condition is satisfied if the result is not \(0\).
Concrete Example
\(N = 3\), \(K = 2\), flower beauty values \(S = [-5, 3, 2]\), contest \((L=1, R=2, P=10)\):
- Select flowers \(\{2, 3\}\) → bit representation
110→ beauty \(3+2=5\), contest mask for \(L=1, R=2\) is011, AND gives `010 \neq 0\( so we participate → total \)5 + 10 = 15$ - Select only flower \(\{3\}\) → bit representation
100→ beauty \(2\), AND with mask011gives `000 = 0\( so we don't participate → total \)2$
Algorithm
- For each contest \(j\), precompute the bitmask
contest_mask[j]corresponding to flowers from \(L_j\) to \(R_j\). - Enumerate all bitmasks
flower_setfrom \(0\) to \(2^N - 1\). - For each
flower_set:- Check that the number of set bits (number of selected flower types) is at most \(K\). Skip if it exceeds \(K\).
- Calculate the total beauty of the selected flowers.
- For each contest, if
flower_set & contest_mask[j]is not \(0\), add the prize money \(P_j\). - Check if the total of beauty + prize money updates the maximum value.
- Output the maximum value (include \(0\) as a candidate for the case where no flowers are selected).
Complexity
- Time complexity: \(O(2^N \times (N + M))\)
- We enumerate \(2^N\) subsets, and for each subset we compute the beauty of \(N\) flowers and check \(M\) contests. Since \(N, M \leq 15\), this is approximately \(32768 \times 30 \approx 10^6\), which is sufficiently fast.
- Space complexity: \(O(N + M)\)
Implementation Notes
Flowers are given as 1-indexed, but in bitmasks we manage them as 0-indexed, so note that flower \(i\) corresponds to bit \(i-1\).
The total value when nothing is selected (
flower_set = 0) is \(0\). By initializing the maximum to \(0\), the output will correctly be \(0\) even when all flower beauty values are negative and participating in contests would only cause a loss.You can easily compute the number of set bits (popcount) using
bin(flower_set).count('1').Source Code
import sys
from itertools import combinations
def main():
input_data = sys.stdin.read().split()
idx = 0
N = int(input_data[idx]); idx += 1
K = int(input_data[idx]); idx += 1
M = int(input_data[idx]); idx += 1
S = [0] * N
for i in range(N):
S[i] = int(input_data[idx]); idx += 1
contests = []
for j in range(M):
L = int(input_data[idx]); idx += 1
R = int(input_data[idx]); idx += 1
P = int(input_data[idx]); idx += 1
contests.append((L, R, P))
# For each contest, precompute the bitmask of flowers that can satisfy it
# Flower i (1-indexed) corresponds to bit (i-1)
contest_mask = [0] * M
for j in range(M):
L, R, P = contests[j]
mask = 0
for i in range(L - 1, R):
mask |= (1 << i)
contest_mask[j] = mask
best = 0 # choosing nothing gives 0
# Enumerate all subsets of flowers with size <= K
# N <= 15, so 2^15 = 32768 subsets
for flower_set in range(1 << N):
count = bin(flower_set).count('1')
if count > K:
continue
# Sum of beauty
beauty = 0
for i in range(N):
if flower_set & (1 << i):
beauty += S[i]
# Sum of contest prizes
prize = 0
for j in range(M):
# Contest j is satisfied if flower_set has at least one flower in [L_j, R_j]
if flower_set & contest_mask[j]:
prize += contests[j][2]
total = beauty + prize
if total > best:
best = total
print(best)
main()
This editorial was generated by claude4.6opus-thinking.
投稿日時:
最終更新: