题目:洞穴里有N堆金币,你有一个背包,最大能承受金币的重量为T,第i堆金币的重量和价值分别为m[i],v[i],你的背包并不一定能够装下所有的金币,所有金币都可进行分割,那么为了装下价值最大的金币,你最多能拿走多少金币?
解题思路:
定义一个状态数组d[i],表示在承重量为i时刻能拿走的金币的最大价值
那么我们有如下的状态转移方程:dp[j]=max(dp[j],dp[j-k]+k*v[i]/m[i]);//因为金币是可以任意分割的
代码如下:
#include <iostream>
#include <algorithm>
#include <vector>
#include <iomanip>
using namespace std;
int main()
{
int n, t;
cin >> n >> t;
vector<int> m(n + 1), v(n + 1);
for (int i = 1; i <= n; i++) {
cin >> m[i] >> v[i];
}
vector<double> dp(t + 1);//dp[i]表示承重为i的背包最多可以拿走的金币价值
for (int i = 1; i <= n; i++) {
for (int j = t; j >= 1; j--) {//j表示当前承重
//k是第i堆金币装入的数量,最多可以装入m[i]个,同时不能超过当前总承重
for (int k = 1; k <= m[i] && k <= j; k++) {
dp[j] = max(dp[j], dp[j - k] + 1.0 * k * v[i] / m[i]);
}
}
}
cout << fixed << setprecision(2) << dp[t] << endl;
return 0;
}