# Dãy đan dấu ## Ý tưởng Xét các dãy con từ dãy ban đầu để tìm ra dãy con đan dấu dài nhất. Ví dụ, nếu ta có dãy $A$ $=$ $\{1, 2, -3, 4,-7, 1\}$ thì các dãy con có thể tạo thành là: - $A_1=\{1, 2, -3, 4,-7, 1\}$ - $A_2=\{2, -3, 4,-7, 1\}$ - $A_3=\{-3, 4,-7, 1\}$ - $A_4=\{4,-7, 1\}$ - $A_5=\{-7, 1\}$ - $A_6=\{1\}$ Các dãy con được tạo có bắt đầu tại một trong số các phần tử của dãy ban đầu. Từ các dãy con được tạo sẽ xác định được dãy con đan dấu của từng dãy con ấy. Trong ví dụ trên dãy đan dấu của từng dãy con là: - $A_1=\{1\}$ - $A_2=\{2, -3, 4,-7, 1\}$ - $A_3=\{-3, 4,-7, 1\}$ - $A_4=\{4,-7, 1\}$ - $A_5=\{-7, 1\}$ - $A_6=\{1\}$ Từ đó, ta sẽ so sánh các dãy đan dấu này để tìm ra kết quả của bài toán. Vậy dãy đan dấu dài nhất của dãy $A$ ban đầu là: $A_2=\{2, -3, 4, -7, 1\}$. ## Cài đặt Bước đầu tiên cần làm là tạo ra các dãy con bắt đầu từ các phần tử trong mảng. Điều này có thể thưc hiện bẳng một vòng lặp với biến lặp là $i$. ```cpp for (int i=0; i<array.size(); i++){ //code } ``` ```python for i in range(0, len(array): #code ``` Tiếp theo là tìm ra xem dãy đan dấu bắt của từng chuỗi con. Ta sẽ sử dụng một vòng lặp nữa với biến lặp $j$ để xét từng phần tử của dãy con. Đoạn code dưới đây sử dụng biến ```size``` -kích cỡ của dãy đan dấu, ```start```, ```end``` - chỉ số bắt đầu và kết thúc của dãy đan dấu trong mảng ban đầu. ```cpp for (int i=0; i<array.size(); i++){ int size=0, start=0, end=0; for (int j=i; j<array.size(); j++){ if (i==j){ size++; start=i; end=j; } else{ if (a[j]*a[j-1]<0){ size=j-i+1; end=j; } else{ break; } } } } ``` ```python for i in range(0, len(array)): size=0 start=0 end=0 for j in range(i, len(array)): if i==j: size++ start=i end=j else: if array[j]*array[j-1]<0: size=j-i+1 end=j else: break ``` Cuối cùng là so sánh các dãy đan dấu và in ra kết quả. Ta sẽ sử dụng $3$ biến ```sizeans, startans, endans``` lưu kết quả. ```cpp int sizeans=0, startans=0, endans=0; for (int i=0; i<array.size(); i++){ int size=0, start=0, end=0; for (int j=i; j<array.size(); j++){ if (i==j){ size++; start=i; end=j; } else{ if (array[j]*array[j-1]<0){ size=j-i+1; end=j; } else{ break; } } } if (size>sizeans){ sizeans=size; startans=start; endans=end; } } cout<<sizeans<<"\n"; for (int i=startans; i<=endans; i++){ cout<<array[i]<<" "; } ``` ```python sizeans=0 startans=0 endans=0 for i in range(0, len(array)): size=0 start=0 end=0 for j in range(i, len(array)): if i==j: size++ start=i end=j else: if array[j]*array[j-1]<0: size=j-i+1 end=j else: break if size>sizeans: sizeans=size startans=start endans=end ``` Độ phức tạp thời gian: $O(n^2)$. ## Cải tiến Thay vì xét hết tất cả các dãy đan dấu của từng dãy con, ta có thể xét từng dãy đan dấu của chuỗi ban đầu. Độ phức tạp thời gian: $O(n)$.