题目

题目大意

约翰的干草库存已经告罄,他打算为奶牛们采购 磅干草。

他知道 个干草公司,现在用 给它们编号。第 公司卖的干草包重量为 磅,需要的开销为 美元。每个干草公司的货源都十分充足, 可以卖出无限多的干草包。

帮助约翰找到最小的开销来满足需要,即采购到至少 磅干草。

输入格式

第 1 行:两个空格分隔的整数:

第 2~N+1 行:第 i+1 行包含两个空格分隔的整数:

输出格式

一个整数,表示 FJ 为获得至少 H 磅干草所需的最低成本。

样例 #1

样例输入 #1

2 15 
3 2 
5 3

样例输出 #1

9

提示

FJ可以从第二个供应商处购买三包,总费用为9

解答

思路

该题为完全背包(不限草垛数量),采用一维滚动数组,因为此题开的数组比较大二维数组浪费空间(一些废话)。

状态转移方程 , 其中 指供应商的编号,指干草的重量,dp[j] 表示 购买j磅干草所耗费的成本。

需要注意的是,题目中指出 purchase at least H pounds of hay.求出购买至少 H 磅干草所需的最低成本。 故干草的重量可以超过H磅。

参考代码


#include <iostream>
using namespace std;

int ans=1e9,N,H,P[101],C[101],dp[55001]; 

int main() {
    cin >> N >> H;
    for (int i = 1; i <= N; ++i) {
        cin >> P[i] >> C[i];
    }

//  初始化
    dp[0] = 0; // 非常重要的一步!在求解只购入一包干草的时候会用到
    for (int i = 1; i <= 55000; ++i) {
        dp[i] = 1e9; // 初始化为无穷大
    }

//  递推求解:完全背包-一维滚动数组
    for (int i = 1; i <= N; ++i) {
        for (int j = P[i]; j <= H + 5000; ++j) {
                dp[j] = min(dp[j], dp[j - P[i]] + C[i]);
        }
    }
    
//  finding the minimum cost necessary to purchase at least H pounds of hay. 求出购买至少 H 磅干草所需的最低成本。
    for (int i = H; i <= H + 5000; ++i) {
        ans = min(ans,dp[i]);
    }
    
    cout<<ans<<endl;
    return 0;
}