* time limit per test: **1 seconds**
* points per test: **1.0 points**
* quantity test: **20 testcase**
* memory limit per test: **1024 megabytes**
* input : **TRISEQ.INP**
* output : **TRISEQ.OUT**
## 1. đề bài ##
**Câu 3: Tam giác**
cho dãy số **a[1], a[2], ..., a[n]** có **n** phần tử nguyên dương, hãy tìm **dãy con dài nhất (có thể các phần tử không liên tiếp)** của dãy số sao cho ba số nguyên dương bất kỳ trong dãy đều có thể là **ba cạnh của tam giác**.
## 2. input ##
* từ tệp văn bản **TRISEQ.INP** có cấu trúc sau:
* dòng đầu ghi số nguyên dương **n**.
* dòng thứ hai ghi **n** số nguyên dương **a[1], a[2], ..., a[n]**.
## 3.output ##
* ghi vào tệp văn bản **TRISEQ.OUT** ghi số nguyên dương độ dài lớn nhất của dãy con tìm được.
* ***chú ý**: dữ liệu luôn được đảm bảo đáp án từ 3 trở lên.*
## 4. ví dụ ##
* **TRISEQ.INP**
```
5
1 2 3 4 5
```
* **TRISEQ.OUT**
```
3
```
* **Giải thích**
```
dãy con thỏa mãn: 2, 3, 4
```
## 5. Subtasks ##
```
Subtasks chung: a[i] ∈ |int32|
Subtasks 1 (30%): 3 <= n <= 15.
Subtasks 2 (40%): 15 <= n <= 1000.
Subtasks 3 (30%): 1000 <= n <= 10^6.
```
## 6. dạng bài ##
* đệ qui
* tham
* twopointer
* toán
## 7. lời giải sơ lược ##
* gọi x, y, z là ba cạnh tam giác.
* --> x+y>z và x+z>y và y+z>x
* Subtasks 1: đệ qui quay lui xác định dãy thỏa mãn điều kiện hoặc sử dụng 3 for để kiểm tra điều kiện thỏa mãn.
* Subtasks 2: sort mảng a, dùng 2 for xác định đoạn [l..r] dài nhất thỏa mãn điều kiện.
* Subtasks 3: sort mảng a, sử dụng kĩ thuật 2 con trỏ tìm đoạn dài nhất thỏa mãn điều kiện. O(nLogn)
## 8. code mẫu ##
```cpp=
#include <bits/stdc++.h>
#define fi first
#define se second
#define all(v) v.begin() , v.end()
#define sz(v) (int)v.size()
#define unq(v) sort(all(v)); v.resize(unique(all(v)) - v.begin());
using namespace std;
typedef long long ll;
typedef pair<int , int> ii;
typedef pair<long long , int> lli;
const int maxN = int(1e6)+7;
int n , a[maxN];
namespace sub1{
bool check(){
return n <= 15;
}
void solve(){
int ans = 0;
for (int mask = 0 ; mask < (1<<n) ; mask++){
vector<int> pos;
for (int i = 0 ; i < n ; i++) if ((mask>>i)&1) pos.push_back(i + 1);
bool check = true;
for (int i = 0 ; i < sz(pos) ; i++){
for (int j = i + 1 ; j < sz(pos) ; j++){
for (int k = j + 1 ; k < sz(pos) ; k++){
if (a[pos[i]] + a[pos[j]] <= a[pos[k]]) check = false;
}
}
}
if (check == true && __builtin_popcount(mask) >= 3) ans = max(ans , __builtin_popcount(mask));
}
cout << ans << "\n";
}
}
namespace sub2{
bool check(){
return n <= 1000;
}
void solve(){
int ans = 0;
for (int i = 1 ; i <= n ; i++){
for (int j = i + 2 ; j <= n ; j++){
if (a[i] + a[i + 1] > a[j]) ans = max(ans , j - i + 1);
}
}
cout << ans << "\n";
}
}
namespace sub3{
void solve(){
int ans = 0;
for (int i = 1 , j = 0 ; i + 2 <= n ; i++){
while (j + 1 <= n && a[i] + a[i + 1] > a[j + 1]) j++;
if (j - i + 1 >= 3) ans = max(ans , j - i + 1);
}
cout << ans << "\n";
}
}
void solve(){
cin >> n;
for (int i = 1 ; i <= n ; i++) cin >> a[i];
sort(a + 1 , a + n + 1);
if (sub1::check()) return sub1::solve();
if (sub2::check()) return sub2::solve();
return sub3::solve();
}
#define name "TRISEQ"
int main(){
ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
freopen(name".inp" , "r" , stdin);
freopen(name".out" , "w" , stdout);
int t = 1; //cin >> t;
while (t--) solve();
return 0;
}
```