1. Trang chủ
  2. » Công Nghệ Thông Tin

Bàn về một bài toán hay trong Pascal

3 1,3K 33
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Bàn về một bài toán hay
Tác giả Nguyễn Hiển
Trường học Trường Đại Học
Thể loại bài viết
Định dạng
Số trang 3
Dung lượng 57 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Bàn về một bài toán hay trong Pascal

Trang 1

Bàn về một bài toán hay

Nguyễn Hiển

Các bạn thân mến! Việc nghiên cứu thuật toán và rút ra kinh nghiệm từ các bài toán hay luôn là một công việc thích thú với các bạn đam mê lập trình Trong bài viết này, tôi muốn giới thiệu với các bạn các cách giải quyết khác nhau cho một bài toán tưởng như đơn giản

A - BÀI TOĂN

Hôm nay, bạn có nhiệm vụ tân trang lại ô tô của mình Tất nhiên, có quá nhiều việc phải làm, vì vậy, bạn muốn thuê các xưởng để sửa chữa làm các công việc đó Không may, các xưởng đó lại rất chuyên môn hoá, cho nên bạn phải thuê các xưởng khác nhau cho các công việc khác nhau Hơn nữa, họ có xu hướng đòi nhiều tiền hơn với các xe ở tình trạng tốt hơn Chẳng hạn, một người thợ sơn có thể đòi tiền nhiều hơn khi sửa 1 ô tô mà toàn bộ nội thất đã làm bằng da, anh ta sẽ không đòi nhiều tiền cho xe chưa bọc da Do

đó, tiền trả thêm phụ thuộc vào công việc nào được làm và các công việc làm trước đó Tất nhiên, bạn luôn muốn tiết kiệm tiền cho mình bằng một thứ tự tốt nhất cho các công việc

Các công việc được đánh số từ 1 tới n Cho giá gốc p của mỗi công việc và tiền trả thêm s

cần tính tổng giá tiền nhỏ nhất để hoàn thành các công việc này.Dữ liệu vào: file

INP.DATDòng đầu tiên của file vào chứa số nguyên n (1 ≤ n ≤ 14) Tiếp theo có n dòng, mỗi dòng chứa đúng n số nguyên: số nguyên thứ i trên dòng này là giá gốc của công việc

nếu công việc j được làm trước đó Các giá tiền là các số nguyên không âm, không vượt quá 100000

Dữ liệu ra: file OUT.DAT

Ghi ra file 1 số nguyên duy nhất là tổng số tiền nhỏ nhất để hoàn thành các công việc.Ví dụ:

B - CĂCH GIẢI QUYẾT

Đây là bài toán có nhiều cách giải, với mỗi cách tiếp cận và suy nghĩ về bài toán, chúng

ta có các cách giải quyết khác nhau:

Trang 2

I CĂCH GIẢI QUYẾT THỨ NHẤT: Duyệt

Dễ thấy, yêu cầu chính của bài toán là sắp xếp n công việc cho trước theo 1 thứ tự xác định để có cực tiểu chi phí Vì thế, cách giải quyết đơn giản nhất là duyệt mọi hoán vị của các công việc và tính ra chi phí nhỏ nhất Rất dễ tính toán ra độ phức tạp của thuật toán là: n! Với cách giải quyết này, theo thử nghiệm của tôi có thể qua được khoảng 8/14 test (một con số không nhỏ dù không tìm được thuật toán tối ưu!)

II CĂCH GIẢI QUYẾT THỨ 2: Dùng lý thuyết đồ thị

Nếu xem xét mỗi công việc như 1 đỉnh của đồ thị, số tiền trả thêm cho công việc i nếu công việc j được làm trước đó là trọng số của cung (có hướng) từ đỉnh j đến đỉnh i Như vậy, bài toán quy về việc xác định 1 đường đi Hamilton có chi phí cực tiểu Dễ dàng cài đặt thuật toán tìm đường đi Hamilton trên đồ thị có hướng, nhưng thực tế thuật toán tìm đường đi Hamilton cũng là thuật toán duyệt, độ phức tạp không khác phương pháp 1

III CĂCH GIẢI QUYẾT THỨ 3: Quy hoạch động

Cách giải quyết đúng đắn nhất cho bài toán này chính là thuật toán tôi muốn đưa ra để bàn luận với các bạn: Thuật toán Quy hoạch động trên tập hợp

Chúng ta có một cách tiếp cận khác về bài toán như sau:

- Xét 1 tập hợp a công việc (có thứ tự) đã được làm (ta đánh thứ tự là 1 a), giả sử chi phí

trên thì chi phí mới sẽ là:

Với một cách tổ chức dữ liệu hợp lí, ta có thể thực hiện bài toán qui hoạch động khá dễ dàng

- Xét mỗi số nguyên h, coi như 1 tập hợp các công việc: Bit thứ i của số nguyên h sẽ là trạng thái của công việc i, cụ thể: Bit thứ i của số nguyên h mang giá trị 1 nếu công việc i

đã được chọn làm và ngược lại, mang giá trị 0 nếu công việc i chưa được làm Như vậy,

- Xây dựng mảng best, với ý nghĩa: best[h] = số tiền cực tiểu để thực hiện các công việc trong tập h

Như vậy, ta có công thức quy hoạch động để tính giá trị cực tiểu khi kết nạp thêm công việc i:

+ h: tập các công việc của h0 và kết nạp thêm công việc h được làm cuối cùng Dễ thấy,

Chương trình có thể viết đơn giản:

Trang 3

Nếu đã xác định được thuật toán thì việc viết chương trình trên trở nên đơn giản, trong khuôn khổ bài báo, tôi không muốn đưa ra phần cài đặt của chương trình, bạn nào có nhu cầu, xin liên hệ trực tiếp qua email

C - BÀN LUẬN THÊM

- Với thuật toán trên, chương trình chạy rất nhanh với n = 14, thậm chí là n = 20

- Nếu bạn cấp phát 2, 3 mảng động trong TP, bạn hoàn toàn có thể chạy với n = 18

- Nếu viết bằng Free Pascal, do bộ nhớ không hạn chế nên chương trình có thể chạy với n

= 20, thậm chí lớn hơn nữa

Kết luậnNhư vậy, với 1 bài toán tưởng như đơn giản, nhưng với cách tiếp cận khác nhau,

ta có các phương án giải quyết khác nhau, do đó thu được các kết quả rất khác nhau Chỉ

có đào sâu suy nghĩ, so sánh, cân đối phương pháp và quá trình thực hiện mới giúp ta tìm

ra thuật toán tối ưu cho chương trình của mình

Ngày đăng: 07/09/2012, 10:30

TỪ KHÓA LIÊN QUAN

w