배낭 구 스트레스 세 : 여러 배낭 문제 : 선택할 수 항목의 유한 수

N 제품의 종류 및 V.의 배낭의 용량이 있습니다
i 번째 항목 SI 부분까지 각 볼륨 VI, 값 (WI)이다.
배낭에 항목을 해결하는은 배낭의 기사 용량의 총량과 최대 값의 합을 초과 할 수 없다.
최대 출력값.
입력 형식
두 정수 공백으로 구분 N, V,의 첫 번째 행은, 각 상품의 종류 및 배낭 볼륨을 나타낸다.
이어서 N 행, VI는 WI가, Si를 공백으로 구분하여 각각 i 번째 항목의 값과 양의 부피를 나타내는 세 개의 정수의 각 행에있다.
출력 형식
최대 값을 나타내는 출력 할 정수.
데이터 범위
0 <N≤1000
0 <V≤20000
0 <VI, WI, si≤20000
SAMPLE INPUT
4 5
1 2 3
2 4 1
(3) (4) (3)
4 5
샘플 출력
(10)
무한이 유한이됩니다 만 여러 배낭 문제 배낭 문제의 상당 가능한 항목의 수에 완전하게 될 것입니다. 그래서 전체 배낭 문제가되기 전에 가장 쉬운 방법은 재주기 최적화 세 번째는 조금 변경하지 않는 것입니다 :
대 (INT에 K = 1; K <= S [i]를 && K <= J / V [I] ++ K)
1 이진 최적화 방법, 시간 복잡도 : O (N * 로그 * V)
. (1) #INCLUDE <iostream>
 2 #INCLUDE <벡터>
 . (3) #INCLUDE <알고리즘>
 . (4)  은 USING  스페이스 STD]
 . 5  구조체 좋은 {
 6.      INT VI, WI]
 . 7  }
 . 8  CONST  INT ARRAY_SIZE = 2001 ]
 . 9  INT F [ARRAY_SIZE] N은, V가, V는, W, S,
  벡터 <좋음> 용기;
 . 11  / * 
12 인  이진 최적화 방법
 (13)은  , V, W S
 (14)  각각의 문서의 부분으로 분할하고, 그 기록 (들)의 최대 수를 얻어 대표
 15  예 : 일곱 개 개의 항목, 그것은 1,2,4 (POW (2, k)를 할 수있다 ) 의 조합
 (16) 문서 각각 네 개의 문서의 그룹으로서 제 2 조, 행
 17  : 세 항목 각각 볼륨 값으로 분할 일곱 문서에 관한
 18 인  2 * 2 * W ;. 4 V, W V, * V, w * 4. 01 배낭 문제에 번역.
. 19  * / 
20이다  INT 의 main () {
 21는      CIN N >> V]
 (22)가      대해 ( INT I = 0 ; I <N; ++ I) {
 23는          CIN W >> >> V S,
 24           ( INT K = . 1 ; K <= S, K * = 2 ) {
 25              S는 - = K;
 26이다              vessel.push_back {K, K * (V *의 W})
 (27)          }
 (28)         경우 (S> 0 )
 29              vessel.push_back ({S * V, S * 승});
30      }
 31      // 01背包问题算法
(32)      에 대해 (좋지 : 용기)
 33           ( INT J = V, J> = good.vi - J)
 (34)              최대 (F [J]를 F = [J], F [J - good.vi] + good.wi);
35      << COUT [V] F;
36 }
2, 큐 최적화 모노톤
참고 : 모노톤 대기열 : 현재 최소 또는 하위 시퀀스의 최대 시퀀스 길이 "m"을 가져옵니다. 단조로운 증가 및 감소 큐 큐의 두 종류입니다. 큐로 모노톤 푸시 대신 원래 시퀀스의 인덱스 값이다.
때 첨자를 "I"밀어 :
(1) deque.front ()을 <시간 = 메신저 그것을 나타 경우;
(2) F [deque.back ()]> F는 [I] 팝업 후 작은 원경 크다 팝;
(3) 푸시 下 标 "I".
) (마지막 deque.front 서브 시퀀스의 현재 최소 시퀀스 길이 "m"입니다.
테스트 케이스 :
10 (100)
8 7 1
2 2~5
2 (3)
8 250 6
107 200
5 2 400
2 1 948
1 1 1
7 4 285
1 (3)
#INCLUDE <iostream> 
#INCLUDE <알고리즘>
 은 USING  스페이스 STD;
 * / 
F : i 번째 항목 이전, 백팩 볼륨 0 V의 최대 값에 대응하는, 
g : I-1 개의 기사 이전, 백팩 볼륨 0 V 해당 최대 값 
* / 
CONST  INT ARRAY_SIZE = 20001 ;
 INT F [ARRAY_SIZE], G [ARRAY_SIZE], Q [ARRAY_SIZE, N, V, V, W, S는,
 INT 의 main () { 
    CIN >> N >> V]
     에 대한 ( INT I = 0 ; I <N; ++ I) { 
        CIN >> >> W V S, 
        복사 (F, F + ARRAY_SIZE, G)
         에 대한 ( INT= J 0 ; J <V; ++ J) {
             INT HH = 0 , TT = - 1. ]
              ( INT K = J, K <= V = K + V) { 
                F [K] = G [K] ;
                 IF는 (HH <&& TT = K - V S *> Q [HH])
                     ++ HH는; // 현재 대기열 시퀀스 헤더 부 내의 큐 요소의 헤드를 제거 최대 값의 소정 범위의 인덱스 
                IF (HH <= TT ) 
                    F [K] = 최대 (F [K], G [Q [HH] + (K - Q [HH]) / V * W) // 최대 값 업데이트 일부 F [K]로 
                그동안 (HH < TT = && g [Q [TT ] - (Q [TT] - J) / V * w <= g [K] - (K - J) / V *W)
                     --tt; // 소자에 사용되지 않는 큐를 제거 
                Q [TT ++] = K; // 새로운 인덱스 값을 푸시 
            } 
        } 
    } 
    COUT << F [V] 
} 
CONST  INT ARRAY_SIZE = 20001 ;
 INT F [ARRAY_SIZE], G [ARRAY_SIZE, N, V, V, W, S, 
양단 큐 < INT > Q;
 INT 의 main () { 
    CIN >> >> N V]
      ( INT I = 0 ; I <N; ++ I) { 
        CIN >> >> W V S;
        복사 (F, F + ARRAY_SIZE, G)
         에 대한 ( INT J = 0 ; J <V; ++ J) {
              ( INT K = J, K <= V = K + V) { 
                F [K] = G [K]
                 IF (! q.empty () && K - V S *> q.front ()) 
                    q.pop_front (); //이 큐 요소의 헤드를 제거는, 특정 범위의 큐 부의 전류 헤드는 최대 시퀀스 인 첨자 
                IF (! q.empty ()) 
                    F [K] = 최대 (F [K], G [q.front ()] + (K - q.front ()) / V * W) // F [K]의 최대 값을 갱신 
                그동안을(q.empty () && G [q.back ()! - (q.back () - J) / V * W <= G [K] - (K - J) / V * W) 
                    q.pop_back (); // 사용되지 큐로부터 제거 
                q.push_back (K); // 새로운 인덱스 값을 푸시 
            } 
        } 
    } 
    COUT << F [V] 
}

추천

출처www.cnblogs.com/xiehuazhen/p/12464870.html