Download as pdf or txt
Download as pdf or txt
You are on page 1of 2

4/30/24, 10:11 PM Chặt nhị phân và các biến thể – part 2 | Nhan Nguyen

Nhan Nguyen

Simplicity is the ultimate sophistication

Chặt nhị phân và các biến thể – part 2

 21.02.201616.03.2017  nhannguyen95  Algorithm  algorithm, binary search, write


Part 1: link here (https://nhannguyen95.wordpress.com/2015/11/30/chat-nhi-phan-va-cac-bien-
the/)

Hôm nay đẹp trời + yêu đời, viết tiếp cái part 2 chơi :v, tiện cũng sửa lại đống code ở Part 1, nhìn
lại mới biết lúc đó mình code ngu ko tả được :angry:

Part 2 mình sẽ trình bày cách chặt nhị phân trên mảng tăng giảm.
Vấn đề đặt ra như sau:

Problem: Cho hàm f(x) nửa tăng nửa giảm ( hoặc nửa giảm nửa tăng) trên đoạn [a;b], tìm x’ sao
cho f(x) đạt cực trị tại đó ( cực đại hoặc cực tiểu ).

Sau đây là đoạn code tìm cực tiểu hàm f(x) trên đoạn [lo,hi]

1 double bsearch(double (*f)(double), double lo, double hi) {


2
3 const double eps = 0.01;
4 double ans = lo;
5
6 while(abs(lo-hi) > eps) {
7
8 double m = (lo + hi) / 2;
9 double l = m - eps;
10 double r = m + eps;
11
12 if (f(l) < f(m)) {
13 ans = l;
14 hi = l;
15 } else if (f(r) < f(m)) {
16 ans = r;
17 lo = r;
18 } else {
19 ans = m;
20 break;
21 }
22 }
23
24 return ans;
25 }

+ Điều kiện lặp thực chất vẫn là lo <= hi, nhưng ta đang làm việc trên số thực nên cần có sai số eps
để so sánh

Advertisement

https://nhannguyen95.wordpress.com/2016/02/21/chat-nhi-phan-va-cac-bien-the-part-2/ 1/2
4/30/24, 10:11 PM Chặt nhị phân và các biến thể – part 2 | Nhan Nguyen

+ Do toàn bộ hàm f hiện tại không còn tuyến tính, nên để biết được sự dịch chuyển của lo và hi, ta
cần phải xét 2 vị trí lân cận nằm về 2 phía của m là l và r

*nếu f(l) < f(m), chứng tỏ nếu ta tiếp tục theo hướng trái, sẽ gặp cực tiểu. Tiến hành lưu kết quả, và
bỏ toàn bộ phần từ m đến hi ( hi = l)

* nếu f(r) = f(l) và f(m) >= f(r), thì (m, f(m)) chính là điểm cực tiểu => thoát vòng lặp.

Trường hợp mảng 1 chiều, chính là sự rời rac của hàm liên tục f(x).
Problem: Cho màng a nửa tăng( giảm) nửa giảm ( tăng). Tìm vị trí mid sao cho a[mid] là max (
hoặc min)

1 int bsearch(int * a, int lo, int hi) {


2
3 int ans = -1;
4
5 while(lo <= hi) {
6
7 int m = (lo + hi) / 2;
8 int l = m - 1;
9 int r = m + 1;
10
11 if (a[l] < a[m]) {
12 ans = l;
13 hi = l;
14 } else if (a[r] < a[m]) {
15 ans = r;
16 lo = r;
17 } else {
18 ans = m;
19 break;
20 }
21 }
22
23 return ans;
24 }

Ứng dụng: http://vn.spoj.com/problems/MINCUT/ (http://vn.spoj.com/problems/MINCUT/)

Happy coding

Blog at WordPress.com. (https://wordpress.com/?ref=footer_blog)

https://nhannguyen95.wordpress.com/2016/02/21/chat-nhi-phan-va-cac-bien-the-part-2/ 2/2

You might also like