dp에서 자주 이용되는 확장 방법 입니다.
입력 데이터가 다음과 같고 3 구간으로 나눌 때의 최대값을 알아보겠습니다.
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
6 | 2 | 9 | 8 | 3 | 4 | 7 | 5 | 1 |
점화식을 정의 합니다.
처음 테이블의 구조 입니다.
2 행 4 열이 5 인 이유는 data[3],data[4] 를 한 묶음으로 하고 첫 행(한 묶음일 때의 구간) 에서 dy[1][2] 를 더한 값 입니다.
이 중 최대값이 채워 집니다.
#include <stdio.h> int data[101]; int dy[51][101]; int diff(int m,int n) { int i,max,min; max = min = data[m]; for( i = m +1 ; i <= n ; i++){ if ( max < data[i] ) max = data[i]; if ( min > data[i] ) min = data[i]; } return max - min; } int main() { int i,j,k; int n,ng,max,tmp; scanf("%d %d",&n,&ng); for( i = 1 ; i <= n ; i++){ scanf("%d",&data[i]); } for( i = 1 ; i <= ng ; i++){ for( j = i*2 ; j <= n ; j++){ max = -1; for( k = 2*(i-1) ; k <= j-2 ; k++){ tmp = diff(k+1,j); if ( dy[i-1][k] + tmp> max ) { max = dy[i-1][k] + tmp; } } dy[i][j] = max; } } int ans=-1; for( i = ng*2 ; i <= n ; i++){ if ( dy[ng][i] > ans ) ans = dy[ng][i]; } printf("%d\n",ans); }
O(n^3)
출처:dovelet