部分背包问题的解法

该问题是一个变种的背包问题,允许金币任意分割。通过动态规划算法,定义状态数组dp来表示在特定承重下的最大金币价值。状态转移方程是dp[j]=max(dp[j],dp[j-k]+k*v[i]/m[i]),其中k是第i堆金币装入的数量。最终,dp[t]即为最大价值。
摘要由CSDN通过智能技术生成

题目:洞穴里有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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值