Hướng dẫn giải của OLP 30/4 lần 29 năm 2025 - Khối 11 - Đường đi trên ma trận
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 làm lời giải.
Nộp code mẫu trước khi tự giải được bài tập là một hành vi có thể bị ban.
Tác giả:
Ý tưởng
Bài toán được giải bằng quy hoạch động (Dynamic Programming).
Ta sử dụng mảng ba chiều để biểu diễn giá trị lớn nhất đạt được tại ô với đúng bước đi xuống liên tiếp ngay trước đó.
- : chỉ số hàng hiện tại
- : chỉ số cột hiện tại
- : số bước đi xuống liên tiếp gần nhất (tối đa bước)
Khởi tạo
- Khởi tạo tất cả để biểu thị trạng thái chưa truy cập
- Gán là điểm bắt đầu
Chuyển trạng thái
Với mỗi trạng thái hợp lệ , ta xét 2 hướng đi:
Đi sang phải
Nếu thì:Vì không đi xuống nên
Đi xuống
Nếu và thì:
Kết quả
Kết quả là:
Độ phức tạp
Với giới hạn , số trạng thái tối đa là:
Thuật toán đủ nhanh để chạy trong giới hạn thời gian.
Code
void solve() { cin >> n >> m; for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) cin >> a[i][j]; memset(F, -1, sizeof(F)); F[1][1][0] = a[1][1]; for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { for (int k = 0; k <= 2; k++) { if (F[i][j][k] == -1) continue; // di sang phai if (j + 1 <= m) F[i][j + 1][0] = max(F[i][j + 1][0], F[i][j][k] + a[i][j + 1]); // di xuong neu chua vuot qua 3 buoc lien tiep if (i + 1 <= n && k < 2) F[i + 1][j][k + 1] = max(F[i + 1][j][k + 1], F[i][j][k] + a[i + 1][j]); } } } cout << max({F[n][m][0], F[n][m][1], F[n][m][2]}); }
Bình luận