Chặt nhị phân theo kết quả

4 289 2
Chặt nhị phân theo kết quả

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

Thông tin tài liệu

1 Chặt nhị phân theo kết a Xét toán Cho n đoạn dây điện (1 ≤ n ≤ 105 ) Đoạn dây thứ i có độ dài (0 < ≤ 109 ) Cần phải cắt đoạn cho thành đoạn cho có K đoạn dây có độ dài nguyên Có thể không cần cắt hết đoạn dây cho Mỗi đoạn dây bị cắt có phần cịn thừa khác Yêu cầu: Xác định độ dài lớn đoạn dây nhận Nếu khơng có cách cắt đưa số Dữ liệu: file văn WIRES.INP có cấu trúc Dịng chứa hai số nguyên N, K Dòng thứ i N dòng chứa số nguyên Kết quả: Đưa file văn WIRES.OUT, Một dòng ghi độ dài lớn nhận Wires.inp Wires.out 11 200 802 743 547 539 Giải toán Ta dùng mảng A lưu độ dài đoạn dây, biến Res lưu kết toán, biến sum tổng độ dài N đoạn dây Bài tốn giải giải thuật sau: ta thử độ dài x (x nhận giá trị từ tới (sum div k)), sau kiểm tra xem có cắt K đoạn có độ dài x khơng? Hàm kiểm tra xem có cắt K đoạn có độ dài x sau: Function Check(x: Longint): Boolean; Var i,count:longint; Begin Count:=0; For i:=1 to n Count:= Count + A[i] div x; Check:=(Count>=K); End; Đoạn chương trình xét giá trị x sau: Res:=0;// Res biến lưu kết toán For x:=1 to (sum div k) If Check(x) then Res:=x; Ta thấy hàm Check(x) có độ phức tạp O(n), đoạn chương trình xét giá trị x có độ phức tạp O(nL) với L=min(sum div k, max(ai) ) Theo đề n ≤ 105 ≤ 109 , giải thuật giải toán với liệu nhỏ Để giải trọn vẹn toán ta cần giảm độ phức tạp thuật toán Chi phí hàm Check(x) phụ thuộc vào N, ta giảm số phép thử x sau: Giả sử phạm vi giá trị [dau cuoi], xét giá trị x:=(dau+cuoi) div 2, kết toán x nằm đoạn [x+1 cuoi],Check(x) = true ngược lại kết toán nằm đoạn [dau x-1], trình nàylặp lặp lại dau>=cuoi dừng Đoạn chương trình xét giá trị x viết lại sau: Res:=0; Dau:=0; cuoi:=sum div k+1; While ( dau< cuoi) Begin X:= (dau+cuoi) div 2; If Check(x) then Begin Res:=x;//ghi nhận kết sau lần Check(x)=true Dau:=x+1; End Else cuoi:=x-1; End; Đoạn chương trình chi phí xét giá trị x còn:O(log(cuoi-dau+1) ), độ phức tạp thuật toán O(nlogL) đáp ứng yêu cầu tốn Tư tưởng giảm chi phí xét khả x thuật tốn hồn tồn giống với q trình tìm khóa thuật tốn tìm kiếm nhị phân Các toán áp dụng kỹ thuật chặt nhị phân theo kết thường có yêu cầu tìm giá trị nhỏ lớn Tùy vào yêu cầu mà ta có cấu trúc đoạn chương trình chặt nhị phân khác Trường hợp tìm giá trị lớn nhất: Dau:=a-1; cuoi:=b+1; While ( dau=k then return a[i]; print "Not found" Để ý dịng tơ đỏ (if a[i]>k ) trên, gán right = i a[i] = k Vì kết ln a[i] với i nhỏ Để chọn i lớn nhất, ta thay đổi hai dịng tơ đỏ thành: sort(a); left=1, right=n; i = (left + right) / 2; while (left != i) and (i != right) if a[i]>k then right = i; else left = i; i = (left + right) / 2; for i = right to left if a[i]=cuoi dừng Đoạn... div k+1; While ( dau< cuoi) Begin X:= (dau+cuoi) div 2; If Check(x) then Begin Res:=x;//ghi nhận kết sau lần Check(x)=true Dau:=x+1; End Else cuoi:=x-1; End; Đoạn chương trình chi phí xét giá trị

Ngày đăng: 04/07/2020, 21:03

Từ khóa liên quan

Tài liệu cùng người dùng

Tài liệu liên quan