参考:

ala 的杂货店(第二天)

ala 的杂货店(第二天)

问题

Description 开张的第二天,dzl 再次带着 m 元钱来找 ala,ala 从新拿出了他准备的 n 件物品,每件物品有一个实用值和对应的价格,dzl 想在 m 元钱内买到实用值最多的物品组合。这次由于 ala 拿出的物品比昨天多,所以 dzl 可以很轻松的计算出来。dzl 急着去找女朋友,就想让你帮他解决这个问题。 Input 数据的第一行有两个整数,分别为 n 件物品和 m 元钱 (1n1000,1m1000) 第 i+1 行为第 i 件物品的实用值 c[i] 和价格 w[i] 元 (1c[i],w[i]1000) Output 输出一行为可以得到的最大的实用值。 Sample Input Copy 5 10 1 5 2 4 3 3 4 2 5 1 Sample Output Copy 14

解法

很典型的 0-1 背包问题,枚举 0~m 元可以买到的最多实用值

/** ala store: 0-1背包 */
int alaStoreII(vector<int>& c, vector<int>& w, int m) {
    int n = c.size();
    vector<int> dp(m + 1, 0);
    for (int i = 0; i < n; i++) {
        for (int j = m; j > 0; j--) {
            if (j >= w[i]) {
                dp[j] = max(dp[j], dp[j - w[i]] + c[i]);
            }
        }
    }
    return dp[m];
}

ala 的杂货店(第三天)

问题

Description 开张的第三天,dzl 气势汹汹地带着 m 元钱来找 ala,ala 这次不打算为难他,拿出的 n 种物品中每种物品有一个对应的价格,dzl 想知道花光 m 元钱可以购买的物品方案总数。今天可算是难住 dzl 了,想让你再次帮他解决这个问题。 Input 数据为单组 数据的第一行有两个整数,分别为 n 件物品和 m 元钱 (1n200,1m200) 第 i 行为第 i 种物品的价格 w[i] 元 (1w[i]200) 数据保证没有两种物品价格重复 Output 输出一行为可以购买的方案总数 Sample Input Copy 3 5 1 2 3 Sample Output Copy 5 HINT 样例中可以购买的方案分别为 [2,3],[1,1,3],[1,1,1,2],[1,2,2],[1,1,1,1,1]。

解法

完全背包问题,本质和 零钱兑换问题 一样,枚举 0~m 元可以买的物品方案总数

int alaStoreIII(vector<int>& w, int m) {
    // 完全背包问题,枚举0~m元对应的最大方案数
    int n = w.size();
    vector<int> dp(m + 1, 0);
    dp[0] = 1;
    for (int i = 0; i < n; i++) {
        for (int j = 1; j <= m; j++) {
            if (j >= w[i]) {
                dp[j] = dp[j] + dp[j - w[i]];
            }
        }
    }
    return dp[m];
}