최대 단조로운 하위 시퀀스(DP)
12679 단어 dp
이 문제는 동적 기획의 방법으로 해결할 수 있으며 시간의 복잡도는 O(n^2)이다.
A[t]를 설정하면 서열의 t번째 수를 표시하고 F[t]는 1에서 t까지의 단락에서 t로 끝나는 가장 긴 상승 서열의 길이를 나타낸다.
동적 기획 방정식: F[t]=max{1, F[j]+1}, 그 중에서 (j=1, 2,..., t-1, 그리고 A[j]=상기 공식을 통해 가장 긴 상승 서열의 길이를 max(F(t))로 구한다.
printResultSeq 함수는 귀속 방법을 통해 모든 최장자 서열을 출력합니다.
참조 코드:
1 //seq: ,( );
2 //len: ;
3 //tmpresult: ;
4 //end: F tmpresult , [0,end);
5 //A: ;
6 //F : F;
7 void printResultSeq(int A[],int F[],int end,int tmpresult,int seq[],int len)
8 {
9 for(int i=0;i<end;i++)
10 {
11 if(tmpresult==F[i] && A[i]<=seq[tmpresult+1])
12 {
13 seq[tmpresult]=A[i];
14 if(tmpresult==1)
15 {
16 for(int k=1;k<=len;k++)
17 cout<<seq[k]<<",";
18 cout<<"end"<<endl;
19 return;
20 }
21
22 printResultSeq(A,F,i,tmpresult-1,seq,len);
23
24 }
25 }
26 }
27
28 int fun( int A[] ,int n)
29 {
30 int *F=new int[n+1];
31 int result=0;
32 F[0]=1;
33 for(int i=1;i<n;i++)
34 {
35 F[i]=1;
36 for(int j=0;j<i;j++)
37 {
38 if(A[i]>=A[j])
39 F[i]=max(F[i], F[j]+1);
40 }
41 if(result<F[i])
42 result=F[i];
43 }
44
45 //////////////////print all result
46 int *seq=new int[result+2];
47 seq[result+1]=numeric_limits<int>::max(); //the max of int
48 printResultSeq(A, F, n, result,seq,result);
49
50 return result;
51 }
---------------------------------------------------------------------------
다음은 개선된 O(nlogn) 알고리즘입니다.
우리는 F[t]를 계산할 때의 상황을 자세히 고려했다.요소 A[x]와 A[y]가 두 개 있다고 가정하면 (1) x < y < t
(2)A[x] < A[y] < A[t]
(3)F[x] = F[y]
이때 F[x]를 선택하는 것과 F[y]를 선택하는 것은 모두 같은 F[t]값을 얻을 수 있다. 그러면 가장 긴 상승자 서열의 이 위치에서 A[x]를 선택해야 하나요, 아니면 A[y]를 선택해야 하나요?
분명히 A[x]를 선택하는 것이 A[y]를 선택하는 것보다 낫다.조건 때문에 A[x+1]에서...A[t-1] 이 단락에 A[z], A[x] 이상의 분석에서 우리는 다음과 같은 결론을 얻었다.
만약 우리가 A[0:t-1]의 가장 긴 단조로운 상승자 서열의 길이가 k이고 모든 길이가 k인 상승자 서열 중 마지막 요소의 최소값(b[k]이라고 기록)을 알고 있다면 우리의 관건은 이 수조 b[]를 유지하는 것이다.
그러면 A[t]>=b[k]이면 A[0:t]의 가장 긴 단조로운 상승자 서열의 길이는 k+1이고 b[k+1]=A[t];(결론1)
A[t]만약에 b[1]=참조 코드:
1 int binary(int b[],int k,int key)
2 {
3 if(key<b[1])return 1;
4 int low=1,high=k;
5 while(low!=high-1)
6 {
7 if( b[k=(low+high)/2] <= key )low=k;
8 else high=k;
9 }
10 return high;
11 }
12
13 int fun2(int A[] ,int n)
14 {
15 int *b=new int[n+1],k=1;
16 b[1]=A[0];
17 for(int i=1;i<n;i++)
18 {
19 if(A[i]>=b[k])b[++k]=A[i];
20 else b[binary(b,k,A[i])]=A[i];
21 }
22 return k;
23 }
이 알고리즘이 어떻게 모든 결과를 인쇄하는지에 대해 아직 연구하지 않았다??????
또 다른 방법은 먼저 원수 그룹의 정렬을 A1로 한 다음에 A와 A1의 가장 긴 공통 서열을 구하는 것이다
프로그래밍의 아름다움을 참고할 수 있는 2.16 구수조 중 가장 긴 체증자 서열
[판권 성명] 전재는 출처를 밝혀 주십시오http://www.cnblogs.com/TenosDoIt/archive/2013/04/19/3031589.html
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
【경쟁 프로 전형적인 90문】008의 해설(python)의 해설 기사입니다. 해설의 이미지를 봐도 모르는 (이해력이 부족한) 것이 많이 있었으므로, 나중에 다시 풀었을 때에 확인할 수 있도록 정리했습니다. ※순차적으로, 모든 문제의 해설 기사를 들어갈 예정입니다. 문자열...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.