【ブルーブリッジカップ】01バックパックの問題

1.問題の説明

あるN個の数の項目は、各項目は、重量有しWと値VをMの重量を保持できるバックパックがあります。パックの価値を最大化するために、どのようにパックするかを尋ねます(各アイテムに1つのみ)

入る:

入力の最初の行には、アイテムの数とバックパックの重量を表す2つの整数nmが含まれています。

次のN行では、各行にWiViの2つの数字があり、アイテムの重量と値を示しています。

出力:

最大値を示す整数を含む1行を出力します。

样例输入:
3 5
2 3
3 5
4 7
样例输出:
8

2つの問題解決のアイデア

問題解決方法:動的プログラミング

  1. f(i、W):バックパックの容量がWの場合、既存のiアイテムをロードでき、バックパックにロードできる最大値(つまり、f(3、5)

  2. 次に、2つの状況があります。

    a.i番目のアイテムf(i-1、W)をロードしないでください

    b.i番目のアイテムf(i-1、W-w [i])+ v [i]をロードします

    これから、状態遷移方程式を推測できます
    。f(i、W)= {f(i − 1、W)w [i]> W(アイテムが重すぎる)max {f(i − 1、W)、f(i − 1、W − w [i])+ v [i]} w [i] <= W f(i、W)= \ begin {cases} f(i-1、W)&\ text {w [i] > W(アイテムが重すぎる)} \\ max \ {f(i-1、W)、&f(i-1、Ww [i])+ v [i] \}&\ text {w [i] < = W} \ end {cases}f i W ={{ f i1 W m a x { f i1 W w [i]> W(アイテムが重すぎるf i1 Ww [ i ] +v [ i ] }W [i]は<= W
    これは:

    表に記入することで解決したすべてのサブ質問への回答を記録します。新しい問題で使用する必要のあるサブ質問を直接抽出できるため、二重計算を回避して時間を節約できます。したがって、問題が最適性の原則を満たした後、動的を使用します。問題解決の計画の中核は、フォームに記入することです。フォームに記入した後、最適な解決策が見つかります。

三、ACコードは以下の通りです

#include<bits/stdc++.h>
using namespace std;
int dp[201][5001];
int main()
{
    
    
    int n,m,z;
    cin>>n>>m;
    vector<int> w,v;
    for(int i=1;i<=n;i++){
    
    
        cin>>z;
        w.push_back(z);
        cin>>z;
        v.push_back(z);
    }
    //规划最优解
    for(int i=1;i<=n;i++){
    
    
        for(int j=1;j<=m;j++){
    
    
            if(j<w[i-1]){
    
    
                dp[i][j] = dp[i-1][j];
                continue;
            }
            dp[i][j] = max(dp[i-1][j], dp[i-1][j-w[i-1]]+v[i-1]);
        }
    }
    cout<<dp[n][m]<<endl;
    return 0;
}

おすすめ

転載: blog.csdn.net/xwmrqqq/article/details/109210578