Đăng ký Đăng nhập
Trang chủ Công nghệ thông tin Quản trị mạng Tài liệu cấu trúc dữ liệu và giải thuật...

Tài liệu Tài liệu cấu trúc dữ liệu và giải thuật

.PDF
52
1099
78

Mô tả:

Tài liệu Cấu trúc dữ liệu và giải thuật
Một số vấn đề cơ sở của Tin học Buổi 3: Cấu trúc dữ liệu và thuật giải Giáo viên: Tạ Thúc Nhu Khoa CNTT trường ĐH Lạc Hồng ĐỆ QUI RECURVE 2 Mã hóa Khái niệm Đệ Qui Một đối tượng được gọi là đệ qui nếu nó hoặc 1 phần của nó được định nghiã thông qua khái niệm về chính nó. Ví dụ: Định nghiã phép toán giai thừa, ký hiệu: N! • (a) Nếu N = 0, thì N! = 1 • (b) nếu N > 0 thì N! = N*(N-1)! Ví dụ: Định nghiã UCLN của 2 số x và y, ký hiệu: UCLN(x, y) • (a)UCLN(x,y) = x nếu y = 0 • (b)UCLN(x,y) = UCLN(y, phần dư của x/y) nếu y<>0 3 Mã hóa Chương trình đệ qui • Một chương trình là đệ qui nếu trong chương trình có lời gọi đến chính nó. Ví dụ: Định nghĩa hàm tính N! theo đệ qui. int GiaiThua(int N) { if (N == 0) return 1; return N * GiaiThua(N - 1); } 4 Mã hóa Một định nghiã đệ qui phải có 2 thành phần: • Thành phần dừng: Không chứa khái niệm đang định nghiã Ví dụ: N! = 1 • Thành phần đệ qui: có chứa khái niệm đang định nghiã 5 Mã hóa Ví dụ: Tính UCLN(x,y) theo thuật toán Euclide • (a)UCLN(x,y) = x nếu y = 0 • (b)UCLN(x,y) = UCLN(y, phần dư của x/y) nếu y<>0 int UCLN(int x, int y) { if (y == 0) return x; return UCLN(y, x % y); } 6 Mã hóa THUẬT GIẢI QUAY LUI BACK TRACKING 7 Mã hóa Tổng quan thuật giải Quay lui (Back Tracking) • Dùng giải bài toán liệt kê các cấu hình • Mỗi cấu hình được xác định bằng cách xây dựng tuần tự từng thành phần trong cấu hình. • Mỗi thành phần được xác định bằng cách chọn lựa dữ liệu trong tập khả năng được đề xuất. Cấu hình một lời giải Tập khả năng X1 K1 X2 K2 8 X3 … … Xn … Km Mã hóa Mô hình thuật giải quay lui: Xác định phần tử Xi bằng đệ quy void Try( int i ) { If (Xi là phần tử cuối cùng trong cấu hình) < Thông báo cấu hình tìm được>; else for ( mọi Kj thuộc tập khả năng đề cử cho Xi) [ if ( Chấp nhận Kj ) ] { Thử chọn Kj cho Xi; Try( i+1); //Gọi đệ quy để xác định phần tử Xi+1 Bỏ ghi nhận Kj đã chọn cho Xi để chọn khả năng khác; } } 9 Mã hóa Hai điểm mấu chốt quyết định độ phức tạp của bài toán là: 1. Xác định tập khả năng đề cử: Phụ thuộc vào việc phân tích nhu cầu dữ liệu của từng thành phần trong cấu hình 2. Kiểm tra khả năng đề cử phải phù hợp với thành phần cần xác định. 10 Mã hóa Bài toán: Liệt kê các dãy nhị phân có độ dài n Phân tích: • Biểu diến cấu hình dãy nhị phân dưới dạng: X[1..n] • Tập khả năng đề cử cho mỗi phần tử Xi là {0, 1} • Thuật giải xác định phần tử Xi của dãy nhị phân như sau: void Try(int i) { if ( i > n ) ; else for (int j =0; j<= 1; j++) { X[ i ] = j; Try( i + 1 ); } } 11 Mã hóa Mã đi tuần: chỉ ra hành trình của quân Mã xuất phát từ một ô trên bàn cờ đi qua tất cả các ô còn lại của bàn cờ, mỗi ô đúng 1 lần. Phân tích: • • Cấu hình lời giải là BC[1..n][1..n] chứa số thứ tự hành trình của quân Mã. 2 (u, v) Tập khả năng chứa các giá trị dùng tính tọa độ các ô kế tiếp 1 (x, y) dx[1..8] = {-2,-1, 1, 2, 2, 1, -1, -2} dy[1..8] = { 1, 2, 2, 1, -1, -2, -2, -1} • Điều kiện chọn khả năng cho bước đi thứ i là Ô được chọn phải : – Thuộc bàn cờ – Và chưa đi qua 12 Mã hóa Thuật giải xác định bước đi thứ i của quân Mã void Try(int i) { int j,u,v; if (i > n*n) ; else for ( j =1; j <= 8 ; j++) { u =x+dx[j]; v = y+dy[j]; if (u >= 1 && u <= n && v >= 1 && v<=n && BC[u,v] = 0) { x = u; y = v; BC[u,v] = i; Try(i+1); x = u-dx[j]; y = v-dy[j]; BC[u,v] = 0; } } } 13 Mã hóa Bài toán: Liệt kê các hoán vị của dãy số {1, 2, .., n} • Biểu diễn cấu hình một hoán vị: X[1..n] • Tập khả năng đề cử: { 1, 2, .., n } • Nhưng do Xi <> Xj với i <> j. Nên phải kiểm tra giá trị đề cử cho Xi phải khác với các giá trị đã chọn cho các thành phần trước đó. Hướng giải quyết chung là tổ chức các biến trạng thái lưu trữ thông tin phục vụ cho việc kiểm tra: Dùng mảng F[1..n] để ghi nhớ tình trạng sử dụng của từng khả năng trong tập S={1, 2, .., n}, với qui ước: F[ j ] = 0 nếu j chưa sử dụng F[ j ] = 1 nếu j đã sử dụng 14 Mã hóa Thuật giải xác định phần tử Xi của một hoán vị void Try(int i) { if ( i > n ) ; else for (int j = 1; j<= n; j++) if (F[j] = 0) { X[i] = j; F[j] = 1; Try( i + 1 ); F[j] = 0; } } 15 Mã hóa Ví dụ: Liệt kê các tập con k phần tử của tập S = {1, 2, .., n}. Trong đó (k <= n) • Biểu diễn cấu hình một tập con K phần tử: X[1..K] • Tập khả năng đề cử: { 1, 2, .., n } • Nhưng do Xi <> Xj với i <> j. Nên các giá trị đề cử cho Xi phải khác với các giá trị đề cử cho các thành phần trước đó Hướng giải quyết: Dùng mảng F[1..N] để ghi nhớ tình trạng sử dụng của từng khả năng trong tập S={1, 2, .., N}, với qui ước: F[ j ] = 0 nếu j chưa sử dụng F[ j ] = 1 nếu j đã sử dụng 16 Mã hóa Thuật giải xác định phần tử Xi của một tập con void Try(int i) { if ( i > K ) ; else for (int j = 1; j<= N; j++) if (F[j] = 0) { X[i] = j; F[j] = 1; Try( i + 1 ); F[j] = 0; } } 17 Mã hóa Một cách giải khác của bài toán tập con Đưa ra điều kiện cho mỗi tập con là : 1 <= X[1] < X[2] < .. < X[ i ] < .. < X[K-1] < X[K] <= N • Nhận xét: X[K] <= N X[K-1] <= X[K] - 1 <= N - 1 … X[ i ] = X[K-(K-i)] <= N - (K - i) • Do đó, ta có thể giới hạn giá trị đề cử cho thành phần X[i] trong khoảng từ : X[i-1]+1 đến (N – K + i) • Để điều này cũng đúng cho cả trường hợp i = 1, ta thêm vào X[0] = 0. 18 Mã hóa Thuật giải xác định phần tử Xi của một tập con void Try(int i) { if ( i > K ) ; else for (int j = X[i-1]+1; j<= N-K+i; j++) { X[i] = j; Try( i + 1 ); } } 19 Mã hóa KỸ THUẬT NHÁNH CẬN 20 Mã hóa Công dụng • Dùng giải quyết bài toán tìm cấu hình tốt nhất trong các cấu hình liệt kê bằng thuật toán quay lui. • Giảm thời gian thực hiện của thuật toán quay lui. Kỹ thuật nhánh cận thêm vào cho thuật toán quay lui khả năng đánh giá cấu hình ở từng bước. Nếu tại bước thứ i đánh giá được cấu hình không tối ưu thì quay lui ngay không cần phải gọi đệ quy tìm tiếp các thành phần khác của cấu hình. 21 Mã hóa Mô hình đánh giá nhánh cận trong thuật toán quay lui: // Khởi tạo cấu hình BESTCONFIG xấu nhất void Init() { } //Mô hình thuật toán quay lui xác định X[i] có đánh giá nhánh cận void Try( int i ) { If (Xi là phần tử cuối cùng trong cấu hình) ; else for ( mọi Kj thuộc tập khả năng đề cử cho Xi) [ if ( Chấp nhận Kj ) ] { Thử chọn Kj cho Xi; if (còn hy vọng tìm ra cấu hình tốt hơn BESTCONFIG) Try( i+1); Bỏ ghi nhận Kj đã chọn cho Xi để chọn khả năng khác; } } 22 Mã hóa Bài toán người du lịch Có n thành phố (được đánh số từ 1 đến n). Một người đi du lịch xuất phát từ một thành phố muốn đi thăm các thành phố khác, mỗi thành phố đúng một lần rồi quay về nơi xuất phát. Giả thiết biết được chi phí đi từ thành phố i đến thành phố j là C[i,j], 1≤ i, j < n. Hãy tìm 1 hành trình cho người du lịch để tổng chi phí theo hành trình này là ít nhất. 2 1 3 3 1 1 2 2 4 4 0 3 2 1 3 0 1 2 2 1 0 4 1 2 4 0 Ma trận chi phí C 23 Mã hóa Phân tích: • Cấu hình lời giải : X[1..n] – X[1] = 1 được xem là thành phố xuất phát. – Một hành trình là một hoán vị của các thành phố 2, .. ,n. • Tập khả năng đề cử : {2, 3,.., n} • Cấu hình BESTCONFIG: – Smin là tổng chi phí thấp nhất đã chọn trong các hành trình tìm được. Khởi tạo ban đầu cho Smin = Cmax * (n + 1), trong đó Cmax là chi phí lớn nhất trong các chi phí C[i, j] đã cho – BestWay[1..n] : chứa hành trình có chi phí thấp nhất. 24 Mã hóa • Các vấn đề cần thực hiện khi xác định thành phần X[i]: 1. Kiểm tra khả năng đề cử cho thành phần X[i] hợp lệ: khả năng đó chưa được chọn cho các thành phần trước X[i]. 2. Ghi nhận tổng chi phí cho hành trình từ X[1] đến X[i]. 3. Dự đoán cấu hình lời giải tốt hơn hay xấu hơn BESTCONFIG 25 Mã hóa 2- Ghi nhận tổng chi phí cho hành trình từ X[1] đến X[i] • Mảng T[1..n] ghi nhận tổng chi phí tại mỗi bước • T[i] chứa tổng chi phí cho hành trình từ X[1] đến X[i] • Nếu thành phố j được đề cử cho thành phần X[i] thì: T[i] = T[i-1] + C[X[i-1], j] • Tổng chi phí của hành trình từ X[1] đến X[n] và trở về X[1] là: T[n] + C[X[n], 1] 2 1 3 3 1 1 2 2 4 26 4 Mã hóa 3- Dự đoán cấu hình lời giải tốt hơn hay xấu hơn BESTCONFIG • Gọi Cmin là chi phí thấp nhất trong các chi phí C[i, j] đã cho. • Sau khi xác định X[i], nếu đi tiếp (n – i +1) thành phố nữa thì chi phí tối thiểu phải là T[i] + Cmin*(n-i+1). • Nếu T[i] + C[i,j]*(n-i+1) < Smin thì có khả năng tìm được hành trình tốt hơn BESTCONFIG, ngược lại thì hành trình tìm được sẽ không tốt hơn BESTCONFIG. 27 Mã hóa Thuật giải xác định thành phần X[i] void Try(int i) { if ( i > n ) if ( T[n] + C[x[n] , 1] < Smin ) { Smin = T[n] + C[x[n] , 1]; Ghi nhận X là hành trình tốt nhất: Bestway = X; } else for (int j = 2; j <= n; j++) if (F[ j ] = 0) { X[ i ] = j; F[ j ] = 1; T[ i ] = T[i -1] + C[ x[i -1], j]; if ( T[ i ] + (n-i+1)*Cmin < Smin) Try( i + 1 ); F[ j ] = 0; } } 28 Mã hóa Bài toán chuỗi 123 Tìm một chuỗi có độ dài n (n <= 100) chỉ gồm các số 1, 2, 3 thỏa mãn điều kiện: 1. Hai chuỗi con bất kỳ liền nhau đều khác nhau 2. Có ít số 3 nhất Ví dụ: n = 9. Chuỗi nào sau đây hợp lệ? 131213212 123212313 123212321 29 Mã hóa Phân tích • Cấu hình lời giải: X[1..n] • Tập khả năng đề cử: { 1, 2, 3 } • Cấu hình BESTCONFIG: 1. Min3: chứa số lượng số 3 ít nhất. Khởi tạo Min3 = n 2. BestStr[1..n]: chứa chuỗi có số lượng số 3 ít nhất. 30 Mã hóa • Các vấn đề cần thực hiện khi xác định thành phần X[i]: 1. Kiểm tra khả năng đề cử cho thành phần X[ i ] hợp lệ: nghĩa là chuỗi X[1..i] không có 2 chuỗi con liền kề giống nhau. 2. Ghi nhận số lượng số 3 có trong chuỗi X[1..i] 3. Dự đoán cấu hình lời giải tốt hơn hay xấu hơn BESTCONFIG 31 Mã hóa 1- Kiểm tra chuỗi X[1..i] không có 2 chuỗi con liền kề giống nhau. Ví dụ: int ChuoiHopLe(int i) 123212321 { 123212321 for (L = 1; L <= i / 2; L++) 123212321 if ( X[(i–L+1) .. i] = X[(i–2L+1) .. (i- L)] ) 123212321 return 0; 123212321 return 1; } 32 Mã hóa 2- Ghi nhận số lượng số 3 trong chuỗi X[1..i] • Mảng T[1..n] ghi nhận số lượng số 3 tại mỗi bước • T[i] chứa số lượng số 3 trong chuỗi X[1..i ] • Nếu giá trị đề cử là 3 thì T[i] = T[i-1] +1, ngược lại thì T[i] = T[i-1] 33 Mã hóa 3- Dự đoán cấu hình lời giải tốt hơn hay xấu hơn BESTCONFIG 131213212 Do 2 chuỗi con kề phải khác nhau nên: 131213212 • Trong 4 số liên tiếp phải có một số 3. 131213212 • Do đó, một dãy con có độ dài là k phải có ít nhất (k / 4) số 3. 131213212 • Sau khi xác định thành phần X[i] và ghi nhận số lượng số 3 trong T[i], ta còn (n – i) thành phần cần xác định. • Do đó, cấu hình tìm được phải có ít nhất (T[i] + (n-i)/4) số lượng số 3. • Nếu (T[i] + (n-i)/4) < Min3 thì có khả năng tìm được cấu hình tốt hơn BESTCONFIG, ngược lại thì cấu hình tìm được sẽ không tốt hơn BESTCONFIG. 131213212 131213212 34 Mã hóa Thuật giải xác định thành phần X[i] void Try(int i) { if ( i > n ) { Min3 = T[n]; Ghi nhận X là chuỗi tốt nhất: BestStr = X; } else for (int j = 1; j <= 3; j++) { X[i] = j; if (ChuoiHopLe( i )) { if (j == 3) T[i] = T[i -1] + 1; else T[i] = T[i -1]; if ( T[ i ] + (n - i)/4 < Min3) Try( i + 1 ); } } } 35 Mã hóa Giải thuật chia để trị (Devide and conquer) 36 Mã hóa Tổng quan giải thuật chia để trị Kỹ thuật chia để trị bao gồm hai quá trình: • Phân chia bài toán đã cho thành các bài toán con cùng loại, lần lượt giải từng bài toán con đó một cách độc lập. • Tổng hợp kết quả từ bài toán con để có lời giải của bài toán ban đầu. Thông thường, chia bộ dữ liệu đầu vào thành các phần riêng rẽ, sau đó gọi 2 thủ tục đệ qui với bộ dữ liệu đầu vào là các phần vừa chia. 37 Mã hóa Một số bài toán tiêu biểu • Tìm nhị phân • QuickSort • Nhân số nguyên lớn 38 Mã hóa Tìm nhị phân trên mảng sắp thứ tự Bài toán : Cho mảng A[1..n] được sắp xếp theo thứ tự không giảm và x. Tìm i sao cho A[i] = x. Phân tích: Do mảng A sắp thứ tự tăng nên x: • Hoặc là bằng phần tử nằm ở vị trí giữa mảng A • Hoặc là nằm ở nửa bên trái (xphần tử ở giữa mảng A ) 39 Mã hóa Thuật giải: Tìm nhị phân trên mảng sắp thứ tự int Bsearch(x, A[ ], int L, int R) { if (L > R) then return -1; else { M = (L + R)/2; If (x = A[M]) return M; If (x < A[M]) return Bsearch(x, A, L, M-1) return Bsearch (x, A, M+1, R) } } 40 Mã hóa Bài toán tương tự: Tìm đường đi cho xe có tải trọng lớn nhất Có N thành phố, cho biết mỗi con đường nối từ thành phố i đến thành phố j (với i <> j) có thể cho xe với trọng tải không quá C[i, j] đi qua. Cho thành phố xuất phát x và thành phố đích y. Hãy tìm một đường đi từ thành phố x tới thành phố y mà trọng tải lớn nhất có thể được. Ý tưởng: • Khởi tạo: Cmax = MAX{Cij} với mọi i khác j; Cmin =Min{Cij} • Xét đoạn [ Cmin , Cmax] 1. Đặt Cm = (Cmax+Cmin) div 2. 2. Ta kiểm tra xem có tồn tại đường đi từ x tới y cho xe có trọng tải Cm hay không? a) Nếu tồn tại đường đi, ta ghi nhận kết quả và xét tiếp đoạn [Cm+1,Cmax]. b) Nếu không tồn tại đường đi, ta chuyển sang xét đoạn [Cmin ,Cm -1]. 3. Lặp lại cho tới khi đoạn có giá trị đầu lớn hơn giá trị cuối. 41 Mã hóa Thuật giải chọn lộ trình có tải trong lớn nhất void Chon(int Cmin, int Cmax) { if (Cmin <= Cmax) { Cm = (Cmin + Cmax)/2; d = 0; //Độ dài lộ trình LoTrinh[0] = x; // Mảng ghi nhận lộ trình đi từ x đến y if (TonTai(LoTrinh, d, x, Cm ) ) { GhiNhan(LoTrinh, d, Cm); Chon(Cm+1, Cmax); } else Chon(Cmin, Cm-1) ; } } 42 Mã hóa Thuật giải kiểm tra tồn tại lộ trình cho xe có tải trọng Cm đi qua int TonTai(LoTrinh[ ], int &d, int i, int Cm) { int j; if ( i = y ) return 1; for (j = 0; j < n; j++) if (F[ j ] = 0 && C[ i ][ j ] >= Cm) { F[ j ] = 1; d++; LoTrinh[d] = j; if (TonTai(LoTrinh, d, j, Cm)) return 1; d--; F[ j ] = 0; } return 0; } 43 Mã hóa Bài toán tương tự Cho N và S là 2 số nguyên dương. Trong đó, N<= 100 và S <= 10100 Biết rằng căn bậc N của một số S là một số nguyên < 106. Hãy tìm căn bậc N của S Ví dụ: S = 30517578125 N = 15 KQ = 5 44 Mã hóa Thuật toán sắp xếp mảng Quick Sort Ý tưởng thuật toán sắp xếp tăng cho dãy X[L .. R] Bước 1: Phân chia dãy X[L .. R] thành 2 dãy con bằng cách: – Chọn giá trị P của 1 phần tử trên dãy X[L .. R] làm mốc phân hoạch. – Đổi chổ các phần tử X[i]>= P với các phần tử X[j]<= P, với i < j – Khi i > j, dãy ban đầu được phân thành 2 phần: 1. X[ L .. j ] chứa giá trị <= P 3. X[ j .. i ] chứa giá trị = P 2. X[ i .. R ] chứa giá trị >= P Bước 2: – Nếu X[L .. j] có hơn 1 phần tử thì sắp xếp tăng dãy X[L .. j] – Nếu X[i .. R] có hơn 1 phần tử thì sắp xếp tăng dãy X[i .. R] 45 Mã hóa Minh họa thuật toán 5 1 7 5 3 6 i 2 9 j 1 7 5 3 i 2 2 1 3 6 5 9 7 6 5 9 7 6 5 9 j 5 i=j 2 1 L 3 5 j i R 2 1 3 7 6 5 9 1 2 3 5 6 7 9 i=R L=j i R 7 9 7 9 j L i=R 6 7 9 L=j 1 2 3 5 5 46 Mã hóa Thuật giải Quick Sort void QuickSort(X[L .. R]) { int i = L; int j = R; P = X[i]; while (i <= j) { while (X[i] < P) i++; while (X[j] > P) j--; if (i <= j) { if (X[i] <> X[j]) Hoanvi(X[i], X[j]); i++; j--; } } if (L < j) QuickSort(X[L ..j ]); if (i < R) QuickSort(X[i .. R]); } 47 Mã hóa Nhân hai số nguyên X.Y có n chữ số Phân tích: • Chia X thành 2 số nguyên có n/2 chữ số: X=A.10n/2+B • Chia Y thành 2 số nguyên có n/2 chữ số: Y=C.10n/2+D X.Y = A.C.10n+(A.D+B.C)10n/2+B.D Mặt khác: R = (A + B)(C + D) = A.C + A.D + B.C + B.D A.D+B.C = R – A.C – B.D Khi đó: X.Y = A.C.10n+(R-A.C-B.D)10n/2+B.D • Phép nhân với 10n thực chất là thêm n chữ số 0 • 3 phép nhân số nguyên lớn n/2 chữ số :A.C, B.D, (A+B)(C+D) tiếp tục được phân chia cho đến khi 2 toán hạng chỉ có một chữ số. 48 Mã hóa Ví dụ: nhân X=981 với Y=1234. • Trước tiên chúng ta điền thêm vào toán hạng ngắn hơn các số 0 vô nghĩa để làm cho hai toán hạng có cùng độ dài: 981 trở thành 0981. • Sau đó tách từng toán hạng thành hai nửa: X = 0981 cho ra A = 09 và B = 81 è 981 = A.102 + B Y = 1234 thành C = 12 và D = 34 è 1234 = C.102 + D • Do đó, tích cần tìm có thể tính được là: P = A.C = 09 * 12 = 108 Q = B.D = 81 * 34 = 2754 R = (A + B)(C + D) = 90 * 46 = 4140 và cuối cùng 981 x 1234 = P.104 + (R – P – Q).102 + Q = 1080000 + 127800 + 2754 = 1210554. 49 Mã hóa Thuật giải: Nhân 2 số nguyên có n chữ số SoLon Nhan(SoLon X, SoLon Y, int n) { If ( n = 1) return X*Y; A=left(X,n/2); B=right(X,n/2); C=left(Y,n/2); D=right(Y,n/2); P = Nhan(A,C,n/2); Q = Nhan(B,D,n/2); R = Nhan(A+B,D+C,n/2); return (P*10n +(R-P-Q)*10n/2 + Q); } 50 Mã hóa Một số bài toán buổi 3 1. Mỗi hột xí ngầu có 6 mặt, mỗi mặt chứa từ 1 đến 6 dấu chấm. Liệt kê các kết quả phân biệt có thể có khi đổ cùng lúc 3 hột xí ngầu, không kể thứ tự xuất hiện trên các hột xí ngầu, ví dụ {1, 2, 3} và {2, 3, 1} là như nhau. 2. Cho 1 mảng gồm n các số nguyên a[1], a[2],.., a[n] và một số nguyên S. Hãy tìm tất cả các dãy con : 1 <= x1 < x2 < .. < xk <= n sao cho: a[x1] + a[x2] + ..+ a[xk] = S 3. Tính số cách và in tất cả các cách phân tích số tự nhiên N >1 thành tổng các số tự nhiên nhỏ hơn nó (mọi phân tích chỉ kể đúng một lần: 4+3+1 và 1+4+3 chỉ là một) 4. Hãy tìm tập hợp các dấu '+’, ‘-‘ và không dấu giữa dãy số 123456789 sao cho được một biểu thức có giá trị bằng = N cho trước. Ví dụ: N = 280 ta có các tổ hợp sau: 1+2+345-67+8-9; 1+234-5+67-8-9; 123-4+5+67+89 5. Cho một dãy N số nguyên. Hãy loại bỏ khỏi dãy một số phần tử để được một dãy con, có ít nhất 2 phần tử, không giảm và dài nhất. In ra dãy con đó. Ví dụ: N = 10 2 6 -7 5 8 1 -3 5 15 9 Kết quả tìm được dãy con không giảm dài nhất có 4 phần tử: -7 -3 5 9 51 Mã hóa 6. Trên bàn cờ ô vuông 4x4 xếp 8 quân cờ gồm 4 quân màu đen và 4 quân màu trắng sao cho trên mỗi hàng và mỗi cột có đúng một quân màu đen và 1 quân màu trắng. Thể hiện trên màn hình các cách sắp xếp này 7. Một người cha mang theo số tiền là M vào một cửa hàng để mua K món quà để tặng cho các con. Trong cửa hàng có N mặt hàng, mặt hàng thứ i có giá tiền là Ai. Người cha cần chọn K (K < N) mặt hàng khác nhau để làm quà sao cho tổng số tiền của K mặt hàng này không lớn hơn số tiền mang theo và độ chênh lệch giá tiền của K mặt hàng là thấp nhất. 8. Một dây chuyền sản xuất có N (N<=100) vị trí. Có N công nhân, cho biết năng suất của công nhân thứ i mà làm ở vị trí thứ j là Cij (Cij : Integer). Hãy sắp xếp N công nhân vào N vị trí sao cho đạt năng suất cao nhất. 9. Cho ma trận vuông cấp 8 chứa các số nguyên. Tìm giá trị lớn nhất của tổng 8 số hạng trên ma trận số trên sao cho 2 số hạng bất kỳ trong 8 số hạng trên không nằm trên cùng một hàng, không cùng nằm trên một cột và không cùng nằm trên đường chéo . 10. Cho một bảng A có M hàng, N cột (3 ≤ M, N ≤ 50), Mỗi phần tử của bảng là một số nguyên nhận giá trị từ 0 đến 99. Cho một số K (2 ≤ K ≤ Min(M, N)). Tìm K phần tử trong bảng A để tổng của K phần tử này là lớn nhất, với điều kiện là trên mỗi hàng chọn nhiều nhất một phần tử, mỗi cột chọn nhiều nhất một phần tử. 11. Một cơ sở sản xuất cần phân công M nhân viên tham gia thực hiện N hợp đồng sản xuất sản phẩm (M >= N). Mỗi nhân viên chỉ tham gia thực hiện một hợp đồng. Người ta dự tính rằng, nếu phân công i nhân viên tham gia thực hiện hợp đồng j thì có thời gian hoàn thành hợp đồng là T[i,j]. Hãy tìm phương án phân công mỗi hợp đồng bao nhiêu nhân viên sao cho tổng số thời gian hoàn thành N hợp đồng là ít nhất. 52 Mã hóa
- Xem thêm -

Tài liệu liên quan