Hướng dẫn giải của Hoàng Tử Lai
Chỉ dùng lời giải này khi không có ý tưởng, và đừng copy-paste code từ lời giải này. Hãy tôn trọng người ra đề và người viết lời giải.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.
Hướng tiếp cận
Với , duyệt tất cả tập con là quá chậm. Ta sử dụng kỹ thuật Meet-in-the-Middle: chia nguyên liệu thành hai nửa, duyệt tập con mỗi nửa, rồi kết hợp kết quả bằng bảng băm.
Nhận xét quan trọng
Chia nguyên liệu thành nửa trái () và nửa phải (). Mỗi nửa có tối đa tập con — hoàn toàn khả thi.
Với mỗi tập con của nửa trái, ta tính cặp là tổng độ chua và tổng độ đắng. Lưu vào bảng băm: số lượng.
Với mỗi tập con của nửa phải có tổng , ta cần tìm trong nửa trái các tập con có tổng .
Cần dùng cả hai tính chất làm khóa. Nếu chỉ dùng một tính chất sẽ đếm thừa.
Thuật toán
Chia đôi: Nửa trái gồm nguyên liệu . Nửa phải gồm nguyên liệu .
Duyệt nửa trái: Với mỗi bitmask :
- Tính = tổng của các nguyên liệu trong mask
- Thêm vào bảng băm:
map[(s_a, s_b)]++
Duyệt nửa phải và kết hợp: Với mỗi bitmask :
- Tính = tổng của các nguyên liệu trong mask
- Tra bảng băm:
ans += map[(A - s'_a, B - s'_b)]
Kết quả: In
ans.
Độ phức tạp
- Thời gian: — duyệt tập con mỗi nửa, mỗi tập con tốn để tính tổng. Với : .
- Bộ nhớ: — lưu bảng băm cho nửa trái.
Bình luận