C - プロジェクトの選定 / Project Selection 解説 by admin
Qwen3-Coder-480BOverview
This is a problem of selecting a combination of projects that maximizes profit, subject to budget constraints and conflict relationships between projects.
Analysis
This problem is a combinatorial optimization problem of “which projects to select.” A naive approach is to try all subsets (combinations) of projects. Since the number of projects \(N\) is at most \(18\), the number of subsets is \(2^{18} = 262144\), which is small enough for exhaustive search.
For each subset, we check:
- Does the total cost exceed the budget \(K\)?
- Does the subset contain any pair of conflicting projects?
Among the subsets that satisfy these conditions, we find the one with the maximum total profit.
Since conflict relationships are given as \(M\) pairs, we select two projects from the chosen project list and check whether they are in the conflict list. Python’s itertools.combinations is convenient for this.
To efficiently check for conflicts, we can store the conflict information in a set as tuples (u, v) (where \(u < v\)), enabling fast existence checks.
Algorithm
- Generate all subsets of projects using bitmask enumeration (\(2^N\) subsets).
- For each subset, check the following:
- Is the total cost within the budget \(K\)?
- Are there no conflicting pairs among the selected projects?
- Record the maximum profit among subsets that satisfy the conditions.
Complexity
- Time complexity: \(O(2^N \cdot N^2)\)
- Number of subsets: \(O(2^N)\)
- For each subset, the number of selected projects is at most \(N\), and the number of pairs chosen from them is at most \(O(N^2)\)
- Space complexity: \(O(M + N)\)
- \(O(M)\) for the
setstoring conflict information, \(O(N)\) for the cost and profit arrays
- \(O(M)\) for the
Implementation Notes
Project indices are given as 1-based in the input, but are converted to 0-based for internal processing.
By normalizing conflict information to the form
(u, v)(where \(u < v\)), we ensure correct matching regardless of order.Using
itertools.combinationsmakes it easy to generate pairs of selected projects.Source Code
from itertools import combinations
def main():
import sys
input = sys.stdin.read
data = input().split()
idx = 0
N = int(data[idx]); idx += 1
M = int(data[idx]); idx += 1
K = int(data[idx]); idx += 1
C = [0] * N
P = [0] * N
for i in range(N):
C[i] = int(data[idx]); idx += 1
P[i] = int(data[idx]); idx += 1
conflicts = set()
for _ in range(M):
u = int(data[idx]); idx += 1
v = int(data[idx]); idx += 1
u -= 1
v -= 1
if u > v:
u, v = v, u
conflicts.add((u, v))
max_profit = 0
# 全ての部分集合を試す (bit全探索)
for mask in range(1 << N):
cost = 0
profit = 0
selected = []
for i in range(N):
if mask & (1 << i):
cost += C[i]
profit += P[i]
selected.append(i)
if cost > K:
continue
# 選んだプロジェクト間に競合がないかチェック
valid = True
for u, v in combinations(selected, 2):
if u > v:
u, v = v, u
if (u, v) in conflicts:
valid = False
break
if valid:
if profit > max_profit:
max_profit = profit
print(max_profit)
if __name__ == "__main__":
main()
This editorial was generated by qwen3-coder-480b.
投稿日時:
最終更新: