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] }