Acwing02.01 バックパックの問題

目次

序文

1.問題

2. 考える

2.1 二次元動的計画法

2.1.1 転送方法: f[i][j]

2.1.2 初期化: f[0][0]=0

2.1.3 時間計算量: 0(n^2) 百万レベル

2.1.4 スペースの複雑さ: 2 次元の 100 万レベル 4*1000000/1024/1024≈4MB

3. コードの実装

4. テストサンプル

4.1 入力サンプル

4.2 出力結果

4.3 実績 


序文

yの一般的なアルゴリズムを学んだ後、私はいくつかの考えを書きました

1.問題

N 個のアイテムと容量 V のバックパックがあります。各アイテムは1回のみ使用できます。

i 番目のアイテムのボリュームは vi で、値は wi です。

どのアイテムをバックパックに入れるかを解決すると、これらのアイテムの合計体積がバックパックの容量を超えず、合計値が最大になります。

最大値を出力します。

2. 考える

2.1 二次元動的計画法

f[i][j] は最初の i 項目だけを見ることを意味し、総量が j のとき、最大総量はいくらか

結果=最大{f[n][0~v]}

2.1.1 転送方法: f[i][j]

(1) i 番目のアイテムを選択しない: f[i][j]=f[i-1][j]

(2) i 番目の項目を選択: f[i][j]=f[i-1][jv[i]]

2.1.2 初期化: f[0][0]=0

2.1.3 時間計算量: 0(n^2) 百万レベル

2.1.4 スペースの複雑さ: 2 次元の 100 万レベル 4*1000000/1024/1024≈4MB

3. コードの実装

#include <iostream>
#include <algorithm>
using namespace std;
const int N=1005;
int v[N],w[N];
int f[N][N];
int n,m;
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&w[i],&v[i]);
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            if(j<w[i])
                f[i][j]=f[i-1][j];
            else
                f[i][j]=max(f[i-1][j],f[i-1][j-w[i]]+v[i]);
        }
    }
    printf("%d\n",f[n][m]);
    return 0;
}

4. テストサンプル

4.1 入力サンプル

4 5
1 2
2 4
3 4
4 5

4.2 出力結果

4.3 実績 

 図1

おすすめ

転載: blog.csdn.net/m0_53679998/article/details/129519861