C - お得なショッピングモール巡り / Bargain Shopping Mall Tour Editorial by admin
Claude 4.5 OpusOverview
This is a greedy algorithm problem where you calculate the “net profit” from each shopping mall and select the top \(K\) malls from those with positive net profit.
Analysis
Key Insights
Each mall can be evaluated independently: The decision to visit a certain mall can be made independently of other malls.
Optimal behavior within a mall: Once you visit a mall, it’s beneficial to visit all stores with positive profit margin. Since the profit margin is always positive (\(P_{i,j} \geq 1\)), the optimal strategy is actually to shop at all stores in that mall.
“Net profit” of a mall: The net profit from visiting mall \(i\) can be calculated as follows: $\(\text{Net Profit}_i = \sum_{j=1}^{M_i} P_{i,j} - C_i\)$
The option of not visiting: It’s better not to visit malls with negative net profit. Also, if you don’t visit any mall, the total profit is \(0\), so it’s better not to visit than to end up with a negative total profit.
Problems with the Naive Approach
The approach of “trying all combinations of selecting \(K\) malls from \(N\) malls” would require \({N \choose K}\) combinations, which is far too slow when \(N = 10^5\).
Solution
We leverage the fact that each mall’s value (net profit) can be calculated independently. Since we should greedily select malls with the highest net profit, the problem can be solved by simply sorting and selecting the top malls.
Algorithm
Calculate the net profit of each mall: For mall \(i\), calculate the total profit margin of all stores minus the transportation cost \(C_i\).
Sort by net profit: Sort all malls’ net profits in descending order (from largest to smallest).
Greedy selection: Select up to \(K\) malls starting from those with the highest net profit. However, stop selection when the net profit becomes negative (since it’s better not to select them).
Output the answer: The sum of net profits from selected malls is the answer.
Concrete Example
For example, suppose \(N = 3, K = 2\) with the following malls: - Mall 1: \(C_1 = 100\), store profit margins \([50, 60]\) → Net profit = \(110 - 100 = 10\) - Mall 2: \(C_2 = 200\), store profit margins \([300]\) → Net profit = \(300 - 200 = 100\) - Mall 3: \(C_3 = 500\), store profit margins \([100, 100]\) → Net profit = \(200 - 500 = -300\)
Net profits in descending order: \([100, 10, -300]\)
Selecting top 2 with positive values: Mall 2 and Mall 1 → Total profit = \(100 + 10 = 110\)
Complexity
Time Complexity: \(O\left(\sum_{i=1}^{N} M_i + N \log N\right)\)
- \(O\left(\sum M_i\right)\) to read all store profit margins
- \(O(N \log N)\) to sort \(N\) net profits
Space Complexity: \(O(N)\)
- Array to store each mall’s net profit
Implementation Notes
Due to the constraint \(P_{i,j} \geq 1\), all store profit margins are actually positive. Therefore, “adding only positive profit margins” is equivalent to “adding everything”.
Since malls with negative net profit are not selected, you can
breakand terminate early when the net profit becomes \(0\) or less during the loop after sorting.Values can be up to \(10^9\), so the sum can become very large. In Python, you don’t need to worry about integer overflow, but in C++ and similar languages, you need to use
long long.
Source Code
import sys
def main():
input_data = sys.stdin.read().split()
idx = 0
N = int(input_data[idx]); idx += 1
K = int(input_data[idx]); idx += 1
# Calculate the "net profit" of each mall
# Net profit = (sum of positive profit margins) - C_i
profits = []
for i in range(N):
C = int(input_data[idx]); idx += 1
M = int(input_data[idx]); idx += 1
total_positive = 0
for j in range(M):
P = int(input_data[idx]); idx += 1
if P > 0:
total_positive += P
# Net profit if visiting this mall
net_profit = total_positive - C
profits.append(net_profit)
# Select only malls with positive net profit, and pick the top K
# However, it's better not to select malls with negative net profit
profits.sort(reverse=True)
total = 0
for i in range(min(K, N)):
if profits[i] > 0:
total += profits[i]
else:
break
print(total)
if __name__ == "__main__":
main()
This editorial was generated by claude4.5opus.
posted:
last update: