알고리즘 공부

백준 가장 긴 바이토닉 부분 수열

컴퓨터과학 2023. 9. 29. 19:04

https://www.acmicpc.net/problem/11054

 

11054번: 가장 긴 바이토닉 부분 수열

첫째 줄에 수열 A의 크기 N이 주어지고, 둘째 줄에는 수열 A를 이루고 있는 Ai가 주어진다. (1 ≤ N ≤ 1,000, 1 ≤ Ai ≤ 1,000)

www.acmicpc.net

여기서 포인트는 메모리 기억하는곳이 cnt1, cnt2 를 만들어준다음에 시작지점이 모두 1을 가지고 있어야한다는것을 기억해야합니다. 

그리고 그 시작 부분에서 현재 값을 비교하여 가장 큰 누적값을 합쳐서 다음을 계속 진행합니다. 그러면 가장 큰수로 갈것이고 그다음엔 반대 방향으로 가장 큰 수로 누적하면  이 두개의 메모리 값을 합치면 현재 최대로 긴 수열이 되겠죠 .

그리고 여기서 두 배열을 합치기 때문에 중복값을 1을 빼줍니다. 생각을 많이 해야하는 문제네요 ㅠ 

int main() {
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	
	//수열 s가 어떤 수 sk를 기준으로 
	//s1<s2<<s3<<s4 .... s> s
	//10 20 30 25 20
	//10 20 30 40 
	// {10, 20, 30, 40}, {50, 40, 25, 10} 
	int n;
	cin >> n;
	vector<int>lists;
	vector<int>cnts1(n, 1);
	vector<int>cnts2(n, 1);
	vector<int>anw;
	if (n == 1) {
		cout << 1;
		return 0;
	}
	
	for (int i = 0; i < n; i++) {
		int tmp;
		cin >> tmp;
		lists.push_back(tmp);
	}
	
	for (int i = 0; i < lists.size(); i++) {
		int maxs1 = 0;
		int maxs2 = 0;
		int indexi = (lists.size() - 1) - i;
		for (int j = 0; j < i; j++) {
			if (lists[i] > lists[j]) {
				maxs1 =max(maxs1, cnts1[j] + 1);
			}
			
			int indexj = (lists.size() - 1) - j;
			if (lists[indexi] > lists[indexj]) {
				maxs2 = max(maxs2, cnts2[indexj] + 1);
			}
		}
		cnts1[i] = max(maxs1, cnts1[i]);
		cnts2[ indexi ] = max( maxs2, cnts2[ indexi ]);
	}
	
	for (int i = 0; i < n; i++) {
		int tmpSum = cnts1[i]+ cnts2[ i ];
		anw.push_back(tmpSum);
	
	}
	sort(anw.begin(), anw.end(), greater<>());
	cout << anw[0] - 1;
	
	return 0;
}