[ACWing] 7。混合ナップサック問題

件名アドレス:

https://www.acwing.com/problem/content/7/

持ってNNをNアイテムと1容量はVVですVのバックパック。アイテムの3つのタイプがあります:最初の項目にのみ使用することができます1の11回(0 − 1 0-101つのバックパック); 2番目のタイプのアイテムは無制限に使用できます(フルバックパック); 3番目のタイプのアイテムは最大でsis_iしか使用できませんs時間(複数のバックパック);各ボリュームはviv_iですv、値はwiw_iですwアイテムの総量がバックパックの容量を超えないように、どのアイテムがバックパックにロードされているかを解決し、合計値が最大になります。最大値を出力します。

入力形式:
最初の行の2つの整数、NNNVVスペースで区切られたVは、それぞれオブジェクトの数とバックパックの体積を示します。次はNNですN行、1行あたり3つの整数vi、wi、si v_i、w_i、s_ivws、スペースで区切って、それぞれiiを示しますアイテムの量、価値、数量isi = − 1 s_i = −1s=- 1つの手段IIタイプiのアイテムのみ使用できます111次; s i = 0 s_i=0 s=0iiを意味しますタイプiのアイテムは無制限に使用できます;si> 0 s_i> 0s>>0iiを意味しますiタイプのアイテムはsis_iを使用できますsタイムズ

出力形式:
最大値を表す整数を出力します。

データ範囲:
0 <N、V≤10000<N、V≤10000<N V1 0 0 0
0 <vi、wi≤10000<v_i、w_i≤10000<vw1 0 0 0
−1≤si≤1000-1≤si≤10001s i1 0 0 0

アイデアはまだ動的計画法であり、状態表現はf [i] [j] f [i] [j]です。f [ i ] [ j ]、これは前者iiを意味しますi個のアイテムから選択してください。ボリュームはjjを超えません。j最大値、セクションiiに準拠iアイテムのカテゴリを選択するかどうかを選択します。以下のための1 S_I = -1 - SI =s=- 1は、使用することができます0から1 0-101バックパック再帰;si = 0の場合s_i = 0s=0、完全なバックパックで再帰的に使用できます。si> 0 s_i> 0の場合s>>0、複数のバックパックを再帰的に使用できますが、タイムアウトを防ぐために、ここにバイナリ最適化を追加する必要があります。参考:
1、0から1まで0-101バックパック:https//blog.csdn.net/qq_46105170/article/details/113668186;
2.完全なバックパック:https//blog.csdn.net/qq_46105170/article/details/113834289;
3。複数のバイナリ最適化バックパックバージョン:https//blog.csdn.net/qq_46105170/article/details/113840962

コードは次のように表示されます。

#include <iostream>
using namespace std;

const int N = 1010;
int n, m;
int f[N];

int main() {
    
    
    cin >> n >> m;
    for (int i = 0; i < n; i++) {
    
    
        int v, w, s;
        cin >> v >> w >> s;
        if (s == 0) 
            for (int j = v; j <= m; j++)
                f[j] = max(f[j], f[j - v] + w);
        else {
    
    
        	// 0-1背包问题可以看成是物品只有1个的多重背包问题
            if (s == -1) s = 1;
            // 二进制优化
            for (int k = 1; k <= s; k *= 2) {
    
    
                for (int j = m; j >= k * v; j--) 
                    f[j] = max(f[j], f[j - k * v] + k * w);
                s -= k;
            }

            if (s)
                for (int j = m; j >= s * v; j--)
                    f[j] = max(f[j], f[j - s * v] + s * w);
        }
    }    

    cout << f[m] << endl;

    return 0;
}

時間計算量O(V((N − k)+ ∑ i = 1klog⁡si))O(V((Nk)+ \ sum _(i = 1)^ k \ log s_i))O V Nk +i = 1Klo gs、ここでkkksis_iを使用できますsアイテムタイプの数(つまり、バイナリで最適化されるアイテムタイプの数)、スペースO(V)O(V)O V

おすすめ

転載: blog.csdn.net/qq_46105170/article/details/114298331