LeetCode1774。目標価格に最も近いデザートのコスト(バックパックdp)

題名:

你打算做甜点,现在需要购买配料。目前共有 n 种冰激凌基料和 m 种配料可供选购。而制作甜点需要遵循以下几条规则:

必须选择 一种 冰激凌基料。
可以添加 一种或多种 配料,也可以不添加任何配料。
每种类型的配料 最多两份 。
给你以下三个输入:

baseCosts ,一个长度为 n 的整数数组,其中每个 baseCosts[i] 表示第 i 种冰激凌基料的价格。
toppingCosts,一个长度为 m 的整数数组,其中每个 toppingCosts[i] 表示 一份 第 i 种冰激凌配料的价格。
target ,一个整数,表示你制作甜点的目标价格。
你希望自己做的甜点总成本尽可能接近目标价格 target 。

返回最接近 target 的甜点成本。如果有多种方案,返回 成本相对较低 的一种。

数据范围:
n == baseCosts.length
m == toppingCosts.length
1 <= n, m <= 10
1 <= baseCosts[i], toppingCosts[i] <= 1e4
1 <= target <= 1e4

解決:

令d[i]表示能否组成价格i,
因为基料必选,因此初始化 d[基料价格]1,
因为辅料可选可不选,因此将辅料看作物品,01背包即可,
因为辅料最多可以选两个,所以要跑两轮.

コード:

const int maxm=2e4+5;
int d[maxm];
class Solution {
    
    
public:
    int closestCost(vector<int>& a, vector<int>& b, int x) {
    
    
        memset(d,0,sizeof d);
        for(auto i:a){
    
    
            d[i]=1;
        }
        for(auto i:b){
    
    
            for(int k=0;k<2;k++){
    
    
                for(int c=maxm-1;c>=i;c--){
    
    
                    d[c]|=d[c-i];
                }
            }
        }
        int ans=-1;
        for(int i=0;i<maxm;i++){
    
    
            if(d[i]){
    
    
                if(ans==-1||abs(x-i)<abs(x-ans)){
    
    
                    ans=i;
                }
            }
        }
        return ans;
    }
};

おすすめ

転載: blog.csdn.net/weixin_44178736/article/details/114236556