최 장자 서열
4913 단어 알고리즘
1: 최 장 공통 하위 시퀀스 (LCS)
제목 설명: 두 개의 배열 을 드 리 겠 습 니 다. 숫자 일 수도 있 고 문자열 일 수도 있 습 니 다. 우 리 는 숫자 라 고 가정 합 니 다!예 를 들 어:
X = 1, 5, 6, 4, 1, 3, 7
Y = 1, 1, 6, 8, 3, 4, 7
새로운 배열 S 를 구 합 니 다. 이 배열 의 모든 수 는 X 와 Y 배열 의 공공 수 이 고 원래 배열 의 숫자의 전후 관 계 를 만족 시 킵 니 다. 이런 배열 은 여러 가지 가 있 습 니 다. 예 를 들 어 (1, 1, 1, 3, 7), (1, 6, 7) 등 이 있 습 니 다.동시에 S 배열 의 길이 가 가장 긴 것 은 위의 것 (1, 1, 3, 7) 과 같 고 길이 가 4 라면 바로 답 을 구 하 는 것 입 니 다!
DP 문 제 를 푸 는 데 있어 서 가장 중요 한 것 은 DP 함 수 를 정확하게 구성 할 수 있다 는 것 이다. 잘 구성 할 수 있다 면 반 은 성공 할 것 이다.
dp [i] [j] 는 X 배열 의 앞 i 비트 와 Y 배열 의 앞 j 비트 이전의 LCS 를 표시 합 니 다. 그러면 앞의 세 상태 에서 밀어 낼 수 있 습 니 다.
0 if (i = 0 | j = 0) -- 초기 화, 이해 하기 어렵 지 않 습 니 다. X 든 Y 배열 이 든 길이 가 0 이면 S 배열 은 0 입 니 다.
dp[i][j] = max(dp[i-1][j],dp[i][j-1] if (i, j > 0 & & X [i]! = Y [j]) - S 배열 에 숫자 를 추가 하지 않 으 면 앞에서 만 계승 할 수 있 습 니 다. 하 나 는 X 에서, 하 나 는 Y 에서, 하 나 는 Y 에서 만 볼 수 있 습 니 다.
dp[i-1][j-1] + 1 if (i, j > 0 & & X [i] = Y [j]) -- 두 개가 같다 면 당연히 S 수 조 를 1 로 더 하면 X 와 Y 가 모두 계승 한 것 으로 볼 수 있다
코드 는 간단 합 니 다. for 두 개 를 순환 하면 됩 니 다.
2: 최 장 서브 시퀀스 (LIS)
제목 설명: X 배열, X = 1, 2, 3, 6, 5, 7, 4, 8, 6 같은 배열 을 드 리 겠 습 니 다.
새로운 배열 S 를 구 합 니 다. 이 배열 의 모든 수 는 X 배열 의 수 이 고 S 중의 임 의 두 개의 수 S [i], S [j] 는 j > i & s [j] > s [i] 를 만족 시 킵 니 다. 또한 S 배열 이 가장 긴 것 은 (1, 2, 3, 6, 7, 8) 과 (1, 2, 3, 5, 7, 8), 길 이 는 6 입 니 다.
dp [i] 는 X 배열 의 i 번 째 요 소 를 S 배열 의 기본 요소 로 하 는 가장 긴 하위 서열 의 길 이 를 나타 낸다. 그러면 하위 문제 로 해결 할 수 있다.
dp[i] = max(dp[j]) + 1 0
이 문제 에 대해 말하자면 dp 방정식 은 비교적 쉽게 추측 하고 이해 할 수 있 지만, 시간 복잡 도 는 O (n ^ 2) 인 것 을 발견 할 수 있다. 이것 은 많은 문제 에 대해 받 아들 일 수 없 기 때문에 최적화 해 야 한다. 이것 은 하나의 문제 와 관련 되 고, 가장 긴 서브 시퀀스 의 O (n * lgn) 방법 이다.
방법 은 다음 과 같 습 니 다. 먼저 배열 stack 을 드 리 겠 습 니 다. 가장 긴 증가 서브 시퀀스 (증가 하 는 요구 에 따라 배열 의 맨 위 에 있 는 숫자 가 가장 크 고 맨 끝 에 있 는 숫자 가 가장 적 습 니 다. 스 택 을 사용 하면 더 잘 이해 할 수 있 습 니 다) 를 저장 하고 X 배열 을 스 캔 합 니 다. 만약 에 X [i] 가 배열 의 맨 위 에 있 는 요소 (최대 값) 보다 크 면그러면 이 수 를 stack 배열 에 넣 으 세 요. 상단 요소 보다 작 으 면 stack 배열 에서 X [i] 보다 큰 첫 번 째 수 를 찾 고 X [i] 로 교체 하 세 요. stack 배열 은 질서 가 있 기 때문에 첫 번 째 X [i] 보다 큰 수 를 찾 을 때 2 점 으로 찾 아 할 수 있 습 니 다. 이것 이 최적화 입 니 다!
이 두 가 지 는 모두 매우 간단 한 dp 문제 이지 만 동태 기획 사상 도 포함 되 어 있 습 니 다. 뒤의 많은 문제 에서 당신 은 이런 사상 을 무심코 사용 하 는 것 을 발견 할 수 있 기 때문에 그들 을 잘 이해 하 는 것 이 필요 합 니 다. 그러나 동태 계획 이 넓 고 심오 합 니 다. 그 는 고정된 순서 가 없 기 때문에 많은 것 이 사상 이기 때문에 이 두 가지 만 으로 는 부족 합 니 다!
O (n ^ 2) 의 알고리즘:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <climits>
using namespace std;
const int maxn = 1010;
int n;
int array[maxn], maxv[maxn], lis[maxn];
int main(){
scanf("%d", &n);
for(int i = 1; i <= n; i++){
scanf("%d", &array[i]);
lis[i] = 1;
}
lis[0] = -1;
maxv[1] = array[1];
maxv[0] = INT_MIN;
int maxlis = 1;
for(int i = 1; i <= n; i++)
{
int j;//mav[i] i
for(j = maxlis; j >= 1; j--)
{
if(array[i] > maxv[j])
{
lis[i] = j + 1;
break;
}
}
if(lis[i] > maxlis){
maxlis = lis[i];
maxv[maxlis] = array[i];
}
else if(maxv[j] < array[i] && array[i] < maxv[j + 1])
{
maxv[j + 1] = array[i];
}
}
printf("%d
", maxlis);
return 0;
}
for(j = maxlis; j >= 0; j--) { if(array[i] > maxv[j]) { lis[i] = j + 1; break; } } 그 j 를 구 할 때 2 분 검색 으로 검색 하면 O (n ^ 2) 를 O (nlogn) 로 낮 출 수 있 습 니 다.
#include <iostream>
#include <cstdio>
#include <cstring>
#include <climits>
using namespace std;
const int maxn = 1010;
int n;
int array[maxn], maxv[maxn], lis[maxn];
int binarysearch(int low, int high, int index);
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; i++)
{
scanf("%d", &array[i]);
lis[i] = 1;
}
lis[0] = -1;
maxv[1] = array[1];
maxv[0] = INT_MIN;
int maxlis = 1;
for(int i = 1; i <= n; i++)
{
int j = binarysearch(1, maxlis, i);// array[i]。
if(j != -1)
lis[i] = j + 1;
else
j = 0;
if(lis[i] > maxlis)
{
maxlis = lis[i];
maxv[maxlis] = array[i];
}
else if(maxv[j] < array[i] && array[i] < maxv[j + 1])
{
maxv[j + 1] = array[i];
}
}
printf("%d
", maxlis);
return 0;
}
int binarysearch(int low, int high, int index)
{
int pre = -1;
while(low <= high)
{
int mid = (low + high) >> 1;
if(array[index] > maxv[mid])
{
pre = mid;
low = mid + 1;
}
else
high = mid - 1;
}
return pre;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
【Codility Lesson3】FrogJmpA small frog wants to get to the other side of the road. The frog is currently located at position X and wants to get to...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.