[QUOTE=11520676;34585]Đề nghị đọc kỹ bài trước khi trả lời.
- Bài post ở trên mình chưa nói thuật toán tham lam thì sao đã bảo tôi sai lầm được. Làm sao biết 90% test will be wrong.
- Khái niệm đoạn con, dãy con được định nghĩa rõ ràng trong giải tích cấp 3. Do đó lúc ra đề tôi mặc định là ai cũng biết. Tôi không có ý định đánh đố ai mấy chuyện đó. Tất cả trong tiếng anh đều là subsequence vậy tôi hỏi bạn: Bạn học tin học ở việt nam hay ở 1 nước nào nói tiếng anh? Còn bạn biết rõ 2 khái niệm dễ nhầm lẫn mà vấn hỏi lại, không giải thích. Tôi cho rằng việc đó làm sao nhãng topic này.
- Brute force là rất tự nhiên khi tiếp cận bài này thông qua bài toán trước.
- Quy hoạch động là phân rã bài toán lớn thành các bài toán nhỏ. Tính toán kết quả các bài toán nhỏ, lưu lại các kết quả đó. Sau đó tổng hợp kết quả của các bài toán nhỏ để thu được kết quả bài toán ban đầu. Bạn có thể giải thích các khái niệm tôi không biết:
Half Brute force attack - Dynamic Programming
Fully Dynamic Programming - Mathematics
Với khái niệm quy hoạch động ở trên thì cái thuật toán “Fully Dynamic Programming - Mathematics” được trình bày không được “quy hoạch động” cho lắm: phân rã bài toán ra sao? tổng hợp các bài toán nhỏ thế nào? Mà cái giải thuật này cũng dựa trên dãy tổng trước Si. Mục đích hỏi bài này của tôi cũng là cái dãy Si chứ không phải quy hoạch động hay tham lam. (dãy tổng trước Si được định nghĩa trong toán cao cấp A1). - Challenging - O(log n) :Có thể chứng minh được không có thuật toán nào đọc 1 dãy N phần tử có độ phức tạp tốt hơn O(N) ~> cái này là không cần thiết.[/QUOTE]
Trước hết thì vụ dãy con và đoạn con thì mình nói lại lần cuối nhé. Hãy bỏ cái tư tưởng “đoạn con thì chắc chắn là liên tục”, và “dãy con thì chắc chắn là không liên tục” đi mà nó tùy thuộc vào người ra đề. Tất cả các thuật ngữ đều phải được giải thích rõ. Đó là nguyên tắc ra đề. Thậm chí công thức tính vận tốc chuyển động thẳng đều đề cũng phải cho (nếu bài toán có yếu tố vật lý này), trong khi nó thuộc vật lý lớp 7 đấy. Đề nói cho 1 chuỗi DNA bla bla bla thì cũng phải nói rõ là DNA thì có A T G X chứ ko có cái chuyện “cái này thuộc sinh học lớp 9, các em SV đại học mặc định ai cũng biết…”.
Nếu bạn không phân biệt được “Brute Force” , “Greedy Algorithm” và “Dynamic Programming” thì cứ xem lại cho rõ. G không dựa vào G[x - 1], minG không dựa vào minG[x - 1] thì dựa vào đâu ? Đó là bài toán con. Còn đã là Bottom up DP thì dĩ nhiên là cái tính bài toán lớn = bài toán con + xử lý gì đó, sẽ không rõ ràng như Top down DP, nên việc cài đặt đâu thể nào lúc nào cũng khư khư giữ cái kiểu luôn luôn phải là F = F[x - alpha] + beta đâu ? Ở đây G và minG (các thành phần của F) đều được sử dụng yếu tố G dựa vào G[x - 1] và minG dựa vào minG[x - 1] hết.
In mathematics and computer science, dynamic programming is a method for solving complex problems by breaking them down into simpler subproblems. It is applicable to problems exhibiting the properties of overlapping subproblems which are only slightly smaller[1] and optimal substructure (described below). When applicable, the method takes far less time than naive methods.
The key idea behind dynamic programming is quite simple. In general, to solve a given problem, we need to solve different parts of the problem (subproblems), then combine the solutions of the subproblems to reach an overall solution. Often, many of these subproblems are really the same. The dynamic programming approach seeks to solve each subproblem only once, thus reducing the number of computations. This is especially useful when the number of repeating subproblems is exponentially large.
Cái đề số 2 bạn có nhanh quá hóa sai không đấy ? Example bị sai rồi kìa /
Test case 3 Input = 11, expected output = 11011, given output = 101
Nhận xét: giả sử N = 12 và expected output là 11011 (giả sử thôi nhé, vì thực tế là 21112) dãy A[11] là dãy tìm ra đáp án 11011, còn dãy A[12] có chứa dãy A[11] và kèm theo số 12, như vậy dù đáp án có tìm ra tại A[k], thì nếu xét A[N] với N > k thì ta vẫn tìm ra đáp án. Vậy ta chỉ cần xét A[n] mà không quan tâm tới các TH còn lại.
Vì dãy thứ N lớn nhất là |A[500]| < 500 * 3 = 1500 char, lưu được trong bộ nhớ nên ta sinh dãy này ra luôn cho dễ xử lý. Bài toán trở về: cho 1 chuỗi S độ dài M <= 1500 có 9 loại ký tự a_i, loại bỏ bớt các thành phần của dãy sao cho dãy thu được là palindrome lớn nhất. Tại M có 1500 thôi và tôi đang lười suy nghĩ nên tôi tìm 1 giải thuật tối đa N^2 log N (1500 * 1500 * log 1500 xấp xỉ 10 triệu)
Với mỗi dãy con từ i đến j, viết tắt là P(i,j), P(i,j) = độ dài lớn nhất của dãy palindrome tìm được trong khoảng [i,j], RES(i,j) là dãy palidrome lớn nhất sinh ra trong khoảng [i,j]
Mặc định: P(i,i) = 1,P(i,i + 1) = 2 nếu S* = S[i + 1] và P(i,i + 1) = 0 nếu S* != S[i + 1]
P(i,j) = max(P(i + 1,j),P(i,j - 1),P(i + 1,j - 1) + 2 nếu S* = S[j])
RES(i,j) = RES(i + 1,j) hoặc RES(i,j - 1) hoặc S* + RES(i + 1,j - 1) + S[j] tương ứng với bên trên, ngoài ra trong TH P bằng nhau thì chọn RES lớn nhất (ví dụ 991199 và 911119), để cho tiết kiệm bộ nhớ thì mảng RES là mảng con trỏ char *, chỉ trong TH3 thì mới new mảng mới và lưu. Bài không tới nối thiếu mem đâu, nhưng trong TH là có thiếu memory đi, thì thay vì lưu mảng RES, ta lưu mảng T(i,j) mang nghĩa: palindrome mà nó đến từ, khi P(i,j) = … thì T(i,j) = tương ứng nếu dãy con không phải là palindrome và bằng (ii,jj) nếu dãy con là palindrome. Ví dụ:
1 2 3 3 2 2 thì P(1,4) đến được từ P(2,3), P(2,3) lại là 1 palindrom nên T(1,4) = (2,3); P(0,4) đến từ P(1,4), P(1,4) là palindrome nên T(0,4) = (1,4); còn P(0,5) đến từ P(0,4) chẳng hạn, tuy nhiên P(0,4) không phải là 1 palindrome, nên T(0,5) = T(0,4) = (1,4). Đây là mảng truy vết và dùng nó để so sánh ngay khi độ dài P bằng nhau để chọn chuỗi con nào có giá trị lớn hơn.
Cuối cùng ta chọn ra dãy có vị trí xuất phát sao cho P(x,y) là lớn nhất, nếu có nhiều P(x,y) cùng lớn nhất thì ta dùng mảng T để truy vết xem dãy nào lớn hơn thì ta chọn dãy đó
Bài này dành cho bạn.
Từ tập các bài có trên SPOJ (oi)
4540. Lâu đài cát
Mã bài: CTNEWS
CTN vừa xây xong 1 lâu đài bằng cát !Cũng giống như tất cả các lâu đài khác,trên đỉnh những bức tường , sẽ có những lỗ trống ( để đặt đại bác cho việc phòng thù chẳng hạn) , và về hai phía của lỗ trống- tất nhiên sẽ có 2 vùng cao hơn (xem hình vẽ).
Tạm gọi các vùng cao hơn này là Merlons.Lâu đài có N (1<=n<=25000) Merlons, để thuận tiện ta đánh số chúng từ 1->N;
Merlon thứ I có chiều cao M_i (1<=M_i<=100 000);
Ngài CTN muốn sửa chữa lâu đài thành một mẫu mới , anh ta đã làm một danh sách N số nguyên B_1…B_N (1<=B_i<=100000) , và anh muốn thay đổi chiều cao của các Merlon từ (A1…An) thành (B1..Bn) theo một thứ tự nào đó. Để làm được điều này, anh ta đã thuê một số kỹ sư để thiết kế những Merlon theo ý muốn của mình.Tất nhiên chi phí cho việc này là rất đắt đỏ.
Theo tính toán sơ bộ thì chi phí để tăng chiều cao của một đơn vị là X $$
- Chi phí để giảm chiều cao của một đơn vị là Y $$
Hãy giúp CTN tìm ra phương án để có được bức tường mới mà giá phải trả là nhỏ nhất !
Input
Dòng đầu :3 số N,X,Y cách nhau ít nhất 1 dấu cách
Dòng 2..N+1 :mỗi dòng là 2 số Ai, Bi cách nhau ít nhất 1 dấu cách
Output
Gồm 1 dòng duy nhất là kết quả.
Example
Input:
3 6 5
3 1
1 2
1 2
Output:
11
Có 40 % số test với n<=9; 60 % số test với n<=18.
Chúc bạn may mắn :)). Giám thị không giải thích gì thêm :)) Giám khảo không có mặt để giải thích đề :)) Tất cả các câu trong đề đều rất dễ hiểu nên coi như bạn không cần hỏi. Mọi câu hỏi đều xem như ko có liên quan đến đề bài và không trả lời