Processing math: 90%
Solutions of Chess - MarisaOJ: Marisa Online Judge

Solutions of Chess

Select solution language

Write solution here.


User Avatar tuongll    Created at    4 likes

Trước tiên, ta nghĩ một thuật toán quy hoạch động đơn giản cho bài này. Nhận thấy m nhỏ nên ta nghĩ ngay đến quy hoạch động bitmask: gọi f[i][mask1][mask2] là số cách điền bảng i×m, với cột thứ i1 và cột i lần lượt được xếp các quân mã theo cấu hình mask1mask2. Cách chuyển trạng thái khá đơn giản: f[i][mask1][mask2]=mask3f[i1][mask2][mask3] Thỏa mãn các cấu hình mask1,mask2,mask3 đôi một không mâu thuẫn (mâu thuẫn tức là có hai con mã tấn công nhau). Tới đây ta nhận thấy bản chất công thức truy hồi này vẫn là một công thức truy hồi tuyến tính, từ đó có thể thử áp dụng ngay nhân ma trận để giải. Tuy nhiên, điều này đồng nghĩa với việc ta cần một ma trận vuông kích thước 2×22m=512 khi m=4, nên việc nhân ma trận một lần cũng đã đủ lâu, chưa kể việc ta nhân nó logn lần. Để tối ưu thì ta nhận thấy khi tính f[i][mask1][mask2], ta không cần quan tâm tới các bộ (mask1,mask2) bị mâu thuẫn, vì giá trị của nó chắc chắn bằng 0 rồi. Nếu thử code sinh hết các bộ không mâu thuẫn thì khi m=4, chỉ có 81 bộ thỏa mãn! Khi này, ta chỉ cho vào ma trận các bộ thỏa mãn để tính, nên bây giờ ma trận chỉ có kích thước 162×162, đủ tốt để có thể nhân ma trận logn lần. Code mẫu: cpp#clude<bitsstdc++.h>usingll=longlong;#defeall(a)a.beg(),a.end()#defeSZ(a)()(a).size()usingnamespacestd;constmod