[C ++] 01 배낭 문제

1. 기본적인 문제

N 항목 V와 배낭의 용량이 있습니다. 처음에 \ (I \) 공간 소비 항목 \ (C_I \) , 결과 값은 \ (W_i \) . 합계의 최대 값을 허용 배낭으로 항목을 해결.

1.1 아이디어

이 특징으로 가장 기본적인 배낭 문제입니다 : 각 항목은 하나, 당신은 선택하거나 생략 할 수있다. 상태에 의해 정의 된 하위 문제 : 즉 \ (F는 [I는 V] \) 바로 배낭 가능한 최대 용량 값 (V)에 배치 된 나 상품 전에 나타낸다. 이 상태 천이 방정식 :
\ (F.는 [I는 V]가 \ 최대 = {[. 1-I, V-C_I] F. [. 1-I, V, F. + W_i \} \)

1.2 코어 코드

memset(F[0], 0, sizeof(F[0]));
for (int i = 1; i <= n; ++i) {
    for (int v = 0; v <= V; ++v) {
        if (v >= c[i]) F[i][v] = max(F[i-1][v], F[i-1][v-c[i]] + w[i]);
        else F[i][v] = F[i-1][v];
    }
}
for (int i = 0; i <= V; ++i) ans = max(ans, F[n][i]);

시간 복잡도와 공간 복잡도는 \ (O (NV) \) , 시간 복잡도는 실질적으로 최적화 될 수있어서, 공간 복잡성하지만 이에 최적화 될 수있다 (\) O (V) \ .

memset(F, 0, sizeof(F));
for (int i = 1; i <= n; ++i) {
    for (int v = V; v >= c[i]; --v) {
        F[v] = max(F[v], F[v-c[i]] + w[i]);
    }
}
for (int i = 0; i <= V; ++i) ans = max(ans, F[i]);

2. 프로그램의 수는 추구

질문 봐 : 작은 단품
질문에 대한 그러한 변화를 요구하고, 단지 일반적인 상태 천이 방정식 \ (최대 \)(합계 \) \ 수있다. 각 항목은 예를 들어, 완전히 배낭 문서 전달 방정식이있다
\ (F [I, V] = 합계 \ {F [I-1, V, F [I, V-C_I] \} \)

초기 상태는 \ (F. [0,0] =. 1 \) .

F[0][0] = 1;
for (int i = 1; i <= n; ++i) {
    for (int v = 0; v <= V; ++v) {
        if (v >= c[i]) F[i][v] = F[i-1][v] + F[i-1][v-c[i]];
        else F[i][v] = F[i-1][v];
    }
}
ans = F[n][V];
printf("%d\n", ans); 

전체 추구하는 척하려고합니다

: 질문 봐 포장 문제 [질문 4 NOIp2001 전체 집합]
여기 사실을 (W_i \) \ 입니다 \ (C_I \) .

memset(F, 0, sizeof(F));
for (int i = 1; i <= n; ++i) {
    for (int v = V; v >= c[i]; --v) {
        F[v] = max(F[v], F[v-c[i]] + c[i]);
    }
}
for (int i = 0; i <= V; ++i) ans = max(ans, F[i]);
printf("%d\n", V - ans);

4. 가능한 모든의 볼륨이 추구

: 질문했다 구축 성
각 성 높이의 수를 계산했다.

for (int i = 0; i < n; ++i) {
    int np = 0;
    int now;
    int sum = 0;
    while (1) {
        scanf("%d", &now);
        if (now == -1) break;
        a[++np] = now;
        sum += now;
    }
    if (max_sum < sum) max_sum = sum;
    memset(F, 0, sizeof(F));
    F[0] = 1;
    for (int j = 1; j <= np; ++j) {
        for (int v = sum; v >= a[j]; --v) {
            if (F[v-a[j]] && !F[v]) {
                ++h[v];
                F[v] = 1;
            }
        }
    }
}

추천

출처www.cnblogs.com/szdytom/p/12203393.html