56. 携带矿石资源(第八期模拟笔试)
时间限制:5.000S 空间限制:256MB
题目描述
你是一名宇航员,即将前往一个遥远的行星。在这个行星上,有许多不同类型的矿石资源,每种矿石都有不同的重要性和价值。你需要选择哪些矿石带回地球,但你的宇航舱有一定的容量限制。
给定一个宇航舱,最大容量为 C。现在有 N 种不同类型的矿石,每种矿石有一个重量 w[i],一个价值 v[i],以及最多 k[i] 个可用。不同类型的矿石在地球上的市场价值不同。你需要计算如何在不超过宇航舱容量的情况下,最大化你所能获取的总价值。
输入描述
输入共包括四行,第一行包含两个整数 C 和 N,分别表示宇航舱的容量和矿石的种类数量。
接下来的三行,每行包含 N 个正整数。具体如下:
第二行包含 N 个整数,表示 N 种矿石的重量。
第三行包含 N 个整数,表示 N 种矿石的价格。
第四行包含 N 个整数,表示 N 种矿石的可用数量上限。
输出描述
输出一个整数,代表获取的最大价值。
输入示例
10 3
1 3 4
15 20 30
2 3 2
输出示例
90
提示信息
数据范围:
1 <= C <= 10000;
1 <= N <= 10000;
1 <= w[i], v[i], k[i] <= 10000;
代码如下:
#include <bits/stdc++.h>
using namespace std;
//多重背包
int main()
{
int bagweight,n;
cin>>bagweight>>n;
vector<int> weight(n,0);
vector<int> value(n,0);
vector<int> nums(n,0);
for(int i=0;i<n;i++) cin>>weight[i];
for(int i=0;i<n;i++) cin>>value[i];
for(int i=0;i<n;i++) cin>>nums[i];
vector<int> dp(bagweight+1,0);
for(int i=0;i<n;i++)//遍历商品
{
for(int j=bagweight;j>=weight[i];j--)//遍历背包容量
{
//以上为01背包,然后加一个遍历个数
for(int k=1;k<=nums[i]&&(j-k*weight[i])>=0;k++)//遍历个数
{
dp[j]=max(dp[j],dp[j-k*weight[i]]+k*value[i]);
}
}
}
cout<<dp[bagweight]<<endl;
return 0;
}