trang chủ / bài tập / prophecy / lời giải

Mảnh Ghép Lời Tiên Tri

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.
Tác giả: huunguyenhuunguyen

Hướng tiếp cận

Đây là bài toán Shortest Superstring (Siêu xâu ngắn nhất) — một bài toán NP-hard kinh điển. Tuy nhiên, với N18, ta có thể giải bằng quy hoạch động trên bitmask tương tự bài toán Người du lịch (TSP).

Nhận xét quan trọng

  1. Loại bỏ xâu con: Nếu xâu sj là xâu con (substring) của xâu si, thì sj không đóng góp gì vào siêu xâu — ta có thể bỏ nó. Bước này rất quan trọng vì nếu không loại bỏ, bitmask DP sẽ cho kết quả sai (DP tính overlap giữa suffix/prefix, không tính containment).

  2. Overlap giữa hai xâu: Gọi overlap(i,j) là độ dài dài nhất sao cho hậu tố (suffix) của si trùng với tiền tố (prefix) của sj. Khi nối sj sau si, ta chỉ cần thêm |sj|overlap(i,j) ký tự.

  3. Bài toán tương đương TSP: Tối thiểu hóa tổng độ dài siêu xâu tương đương với tối đa hóa tổng overlap. Mỗi xâu là một "thành phố", và ta cần tìm đường đi qua tất cả thành phố (permutation) sao cho tổng overlap lớn nhất.

Thuật toán

Bước 1: Tiền xử lý
  • Loại bỏ các xâu trùng lặp.
  • Loại bỏ các xâu là xâu con của xâu khác.
  • Gọi m là số xâu còn lại sau khi loại bỏ.
Bước 2: Tính overlap
  • Với mỗi cặp (i,j) trong m xâu, tính overlap(i,j) = độ dài dài nhất k sao cho si kết thúc bằng k ký tự đầu của sj.
  • Có thể tính bằng brute force O(m2·L) hoặc dùng KMP cho hiệu quả hơn.
Bước 3: Bitmask DP
  • dp[mask][i] = độ dài ngắn nhất của siêu xâu chứa đúng các xâu trong mask, kết thúc bằng xâu i.
  • Trạng thái gốc: dp[1i][i]=|si| với mỗi i.
  • Chuyển trạng thái: Với mỗi mask, xâu cuối last, và xâu tiếp theo nxtmask: dp[mask{nxt}][nxt]=min(dp[mask][last]+|snxt|overlap(last,nxt))
  • Đáp án: minidp[(1m)1][i]

Độ phức tạp

  • Thời gian: O(m2·L+2m·m2) trong đó L là tổng độ dài các xâu và m18.
  • Bộ nhớ: O(2m·m)

Bình luận

Không có bình luận tại thời điểm này.

gnatmake 12.2.0 a68g 3.1.2 nasm 2.16.1 as_x64 2.46 awk 1.3.4 gcc 16.1.0 csc 6.12.0.200 g++ 16.1.0 g++-themis 16.1.0 g++17 16.1.0 g++20 16.1.0 g++23 16.1.0 clang++ 22.1.6 dmd 2.112.0 dart 3.12.1 gforth 0.7.3 gfortran 12.2.0 go 1.26.3 groovyc 5.0.6 javac 25.0.3 node 26.2.0 kotlinc 2.3.21 sbcl 2.2.9 lua 5.4.8 nim 2.2.10 fpc 3.2.2 fpc-themis 3.2.2 perl 5.36.0 php 8.5.6 pike 8.0 pypy3 7.3.23 python3 3.14.5 racket 8.7 ruby 4.0.5 rustc 1.96.0 csc 5.3.0 ctoj-scratch 0.0.1 sed 4.9 tclsh 8.6 bun 1.3.14 deno 2.8.1 v 0.5.1 zig 0.16.0