[C ++] 01ナップザック問題

1.基本的な問題

N項目Vとバックパックの容量があります。最初に\(I \)のスペースを消費アイテム(C_I \)\、結果の値は、(W_i \)\和の最大値を可能にするバックパックにアイテムを解きます。

1.1アイデア

各アイテムは一つだけで、あなたが選択するか、省略することができます。これは、によって特徴付けられる最も基本的なナップザック問題、です。サブ問題は状態によって定義される:すなわち\(F [I、V] \) だけバックパック利用可能な最大容量値vに入れ私の項目の前に示します。これは、状態遷移式である:
\(F. [I、V] = maxの\ {F. [1-I、V。]、F. + W_i \ [1-I、V-C_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); 

フル追求するふりをしてみてください3.

:質問を見て梱包問題[質問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