B - 로렌스 HDU - 2,829은 경사 DP DP 전환 방정식을 작성하지 않는다

B - 로렌스

 2829 - HDU 

나는 하드를 찾으 주제는, 하드 DP는이 방정식에 쓸 수 없습니다.

문제에 온라인 솔루션을 읽고,이 전환 방정식 DP를 이해하는 데 시간이 오래 읽기

DP가 [I] [j]가 1 ~ 가리 J의 J 비트 및 I 개의 섹션으로 최소 중량 끝내고

그런 배열 W [A, B], (A)의 중량을 B로하고,이 정의는 접두사되는 것이 아니라, 피사체의 종류 및 중량

이러한 4 5 1 2 개 전략적 가치가 4 * 5 + 1 + 4 * 4 * 2 * 5 + 1 + 5 * 2 * 2 + 1 = 49이다 ㄴ이다. 

[A는 B] 49 = w

그 후, 발을 정의 [I] == 1 난] 수단 승 그 접두사 중량과 발 [I] = 브로 [I-1] + 합 [I-1] * A [i]를

이 w는 [A, B] 직접적으로 도입 될 수 있지만, 접두사에 의해 가압 될 수 있기 때문이다.

求 w [A + 1, B] = 브로 [B] -val [A] - (합 [B] -sum [A]) * 합계 [A]

그런 다음 방정식은 DP 그것을 실행할 수 있습니다

DP는 [내가 J]를 분 (DP [I-1, K] + w [K + 1, J를) =

그러나 직접적인 폭력 N ^ 3은 최적화되어야하고,이 수식은 같은 최적화 식의 기울기 전에 통해 가압되지 않고 위에 확실히 아니다.

만약 DP 일반적 경사 DP 최적화함으로써 최적화 될 수있는 가치가 있는데, [I-1, K] K 첨가.

그리고이 공식 전에 도입 될 수있다 (참조하기 전에 - 진주 HDU - 1300 양자 기울기 DP + D   경사 DP - 3507 - 인쇄 기사이 기사는 HDU했다 )

令 F [H]는 DP가 = [I-1] [H] -val [H] + 합 [H] * 합계 [H]

所以 G [H, K = (F [H] - F [K) / (합계 [H] -sum [K]) <합 [J]

그런 다음 같은 추론한다

I가 있는지> J> K G [I, J]> G [J, K]

1 G [I, J]> Gj에, K]> [t] 합보다 우수한 케이 J는 J 바람직한 비 I

(2) G [I, J]> 합 [t]는> G는 [J는 K] j는 이하 난 후, 바람직하게는, J K의 비율보다 바람직

3 합 [t]> G [I, J]> G [J, K] 우수 우수 비 K j에 j를보다 나는

만약 I> J> K G [I, J] <G [J, K]

1 G [내가 J] <G [J, K] <합 [t]는 k 개의 I의 J 비가 우수 우수 J보다 작

2. G [I, J] <합 [t] <G [J, K] I 우수 우수 비 K j에 j를보다

우수 우수 3 합 [t] <G [I, J] <G [J, K] J 비의 I J K의

이러한 상황에서, J가 확실히 배제 될 그래서 후방으로부터 삽입되면 그 때에 앞 J,이 경사의 기울기 번호와 이전 구성의 수보다 적은 구성하면

음,이 확실히 J 아니다.

이 합이 단순하고 접두어이므로 큐 모노톤 DP를 최적화 할 수있다.

 

   

  

#INCLUDE <cstdio> 
#INCLUDE <CString을> 
#INCLUDE <cstdlib> 
#INCLUDE <알고리즘> 
#INCLUDE <큐> 
#INCLUDE <벡터> 
#INCLUDE <iostream> 
#INCLUDE < 문자열 >
 #DEFINE INF 0x3f3f3f3f
 #DEFINE inf64 0x3f3f3f3f3f3f3f3f
 사용  공간 표준;
CONST의  INT maxn 1E5 + = 10 ; 
타입 정의  LL; 
LL의 DP [ 1100 ] [ 1100 ], 합계 [ 1100 ], 발 [ 1,100]이 [ 1100 ];
INT의 케 [maxn]; 

최대 LL ( int로 I, INT의 J, INT의 K) 
{ 
    리턴 - DP [I 1 [J] - 브로 [J] + 합 [J]를 * 합계 [J] - (DP [I - 1 [K] - 발 [K] + 합 [K] * 합계 [K]); 
} 

(아래하겠다 INT의 J, INT의 K) 
{ 
    리턴 합 [J]를 - 합 [K]을; 
} 

LL DP ( int로 I, INT의 J, INT의 K) 
{ 
    복귀 DP [I - 1 [K] + 브로 [J] - 브로 [K] - (합 [J] - 합 [K]) * 합계 [K ];
}

INT 의 main () 
{ 
    INT의 N, m;
    반면 (는 scanf ( " %의 D % d에 " , N, m) && (N + m)) { 
        합 [ 0 ] = 0 ; 
        발 [ 0 ] = 0 ;
        위한 ( int로 I = 1 ; 나는 <= N; I ++는 ) { 
            는 scanf ( " %의 LLD를 " , & A [I]); 
            합 [I] = 합계 [I - 1 ] + A [I]; 
            발 [I] = 브로 [I - 1 ] + 합 [I - 1* A [I]; 
        } 
         ( INT I = 1. ; I <= N-; I는 ++) DP [ 1이다. ] [I] = 브로 [I]; // 참고이 주제 초기화 
         ( INT I = 2 ; I <= m + . 1 ; I ++ ) {
             INT의 머리 = 0 , 꼬리 = 0 ; // 주의 DP는 [내가 j는 상기 정의의 단부 I 블록의 최소값으로 J 인 
            케 [꼬리 ++] = I - 1이다. ] / / 다음 세그먼트 나 블록으로 분할 될 수 있기 때문에, 앞의 숫자는 적어도 I-1이 고려되어야하고, 참고 경우 누락되지 전체적으로 밖이어서 될 수 
            위해 ( INT의 J = I, J <= N-, J ++ ) { // 이 볼 수 있어야 J 주부터 시작
                상태 (머리 + 1 <꼬리가 && (I, 케 [헤드 + 1 ] 케 [헤드]) <= 합 [J] * 다운 (케 [헤드 + 1 ] 케 [헤드])) 헤드 ++ ; 
                DP는 [I] [J] = DP (I, J, 케 [헤드]);
                상태 (머리 + 1 - <꼬리 (I, J, 케 [꼬리 && 1 ) * 다운 (케 [꼬리 -] 1 ] 케 [꼬리 - 2 ]) <= 최대 (I, 케 [꼬리 - 1 ] 케을 [꼬리 - 2 ]) * 다운 (j, 케 [꼬리 - 1 ])) tail-- ; 
                케 [꼬리 ++] = J; 
            } 
        } 
        의 printf ( " % LLD \ 없음 " , DP [m + 1 ] [N]); 
    } 
    반환  0 ; 
}

 

추천

출처www.cnblogs.com/EchoZQN/p/11402172.html