【動的計画法アルゴリズム演習】day16


1. バックパック一式

1. トピックの紹介

DP42 [テンプレート] コンプリート バックパック
この質問は Niuke.com からのものです。上のリンクをクリックして、練習用の質問ページに入ることができます。
ここに画像の説明を挿入します
ここに画像の説明を挿入します
ここに画像の説明を挿入します
ここに画像の説明を挿入します

2. 問題解決のアイデア

3.コード

#include <iostream>
using namespace std;
#include<vector>
int main() {
    
    
    int n, V;
    cin>>n;
    cin>>V;
    vector<int> v(n, 0);//存放物品到的体积
    vector<int> w(n, 0);//存放物品的价值
    for(int i = 0;i < n; ++i)
    {
    
    
        cin>>v[i];
        cin>>w[i];
    }
    //问题1
    vector<int> dp1(V + 1, 0);//dp[j]表示体积为j的背包至多能装多大价值的物品
    for(int i = 0;i < n; ++i)
    {
    
    
        for(int j = v[i];j <= V; ++j)
        {
    
    
            dp1[j] = max(dp1[j - v[i]] + w[i], dp1[j]);
        }
    }
    cout<<dp1[V]<<endl;
    //问题2
    vector<int> dp2(V + 1, -1);//dp[j]表示体积为j的背包至多能装多大价值的物品
    dp2[0] = 0;//初始化体积为0时的dp值
    for(int i = 0;i < n; ++i)
    {
    
    
        for(int j = v[i];j <= V; ++j)
        {
    
    
            if(dp2[j - v[i]] != -1)
            {
    
    
                dp2[j] = max(dp2[j - v[i]] + w[i], dp2[j]);
            }
        }
    }
    cout<<(dp2[V] == -1 ? 0 : dp2[V])<<endl;
    return 0;
}

4. 走行結果

ここに画像の説明を挿入します

2. 322. 両替交換

1. トピックの紹介

322. 両替
さまざまな額面のコインを表す整数配列のコインと、合計金額を表す整数の金額が与えられます。
合計金額を構成するために必要なコインの最小数を計算して返します。どのコインの組み合わせでも合計金額を満たせない場合は、-1 が返されます。
各種類のコインの数は無限であると考えることができます。
ここに画像の説明を挿入します

2. 問題解決のアイデア

3.コード

class Solution {
    
    
public:
    int coinChange(vector<int>& coins, int amount) {
    
    
        vector<int> dp(amount + 1, INT_MAX);//dp[j]表示要凑成总金额为j所需要的硬币数
        dp[0] = 0;//总金额为0的话,所需硬币数为0
        for(int i = 0;i < coins.size(); ++i)
        {
    
    
            for(int j = coins[i];j <= amount; ++j)
            {
    
    
                if(dp[j - coins[i]] != INT_MAX)//如果等于INT_MAX说明该位置不能被合成,不能使用该位置
                {
    
    
                    dp[j] = min(dp[j - coins[i]] + 1, dp[j]);
                }
            }
        }
        return (dp[amount] == INT_MAX ? -1 : dp[amount]);
    }
};

4. 走行結果

ここに画像の説明を挿入します

3. 518. チェンジエクスチェンジⅡ

1. トピックの紹介

518. Change Exchange II では、
さまざまな額面のコインを表す整数配列のコインと、合計金額を表す整数の金額が提供されます。
合計金額を構成できるコインの組み合わせの数を計算して返してください。合計金額に達しないコインの組み合わせがある場合は、0 が返されます。
各金種のコインが無限にあると仮定します。
質問データは、結果が 32 ビット符号付き整数に準拠していることを保証します。
ここに画像の説明を挿入します
ここに画像の説明を挿入します

2. 問題解決のアイデア

3.コード

class Solution {
    
    
public:
    int change(int amount, vector<int>& coins) {
    
    
        vector<int> dp(amount + 1, 0);//dp[j]表示凑成总金额为j的硬币组合数
        //初始化
        dp[0] = 1;//凑成0的硬币组合只有一种,就是一个硬币也没有;其他位置都初始化为0(为了避免影响结果)
        for(int i = 0;i < coins.size(); ++i)
        {
    
    
            for(int j = coins[i];j <= amount; ++j)
            {
    
    
                if(dp[j - coins[i]] != 0)//如果等于-1,说明该位置无法凑出,所以不能使用该位置
                dp[j] += dp[j - coins[i]];//要求组合数,因此要用+
            }
        }
        return (dp[amount] == 0 ? 0 : dp[amount]);
    }
};

4. 走行結果

ここに画像の説明を挿入します

4. 279. 完全平方数

1. トピックの紹介

279. 完全平方数 整数
n が与えられると、和が n となる完全平方数の最小数を返します。
完全平方数は、値が別の整数の 2 乗に等しい整数です。つまり、その値は、整数と整数を掛け合わせた積に等しい値です。たとえば、1、4、9、16 はすべて完全平方数ですが、3 と 11 はそうではありません。
ここに画像の説明を挿入します

2. 問題解決のアイデア

3.コード

class Solution {
    
    
public:
    int numSquares(int n) {
    
    
        vector<int> dp(n + 1, INT_MAX);//dp[j]表示和为j的完全平方数的最少数量
        dp[0] = 0;
        //dp[0]初始化为0,和为0的完全平方数的数量为0
        //其他位置全部初始化为INT_MAX,避免影响min的结果
        for(int i = 1;i <= n; ++i)
        {
    
    
            for(int j = i * i;j <= n; ++j)
            {
    
    
                if(dp[j - i * i] != INT_MAX)//如果相等,说明该位置不能被组成,因此该位置不能被使用
                dp[j] = min(dp[j - i * i] + 1, dp[j]);
            }
        }
        return dp[n];
    }
};

4. 走行結果

ここに画像の説明を挿入します


要約する

今日はアルゴリズム実習16日目です。
広い心を持ってアポイントを取り、厚く薄く積み重ねて、努力を続けてください。
出典: LeetCode、著作権は LeetCode に属します。
この記事があなたにインスピレーションを与えたなら、著者をもっとサポートしていただければ幸いです。皆さん、ありがとう!

おすすめ

転載: blog.csdn.net/xjjxjy_2021/article/details/131471379
おすすめ