P2240 【深基12.例1】部分背包问题

 题目描述

阿里巴巴走进了装满宝藏的藏宝洞。藏宝洞里面有 N(N≤100) 堆金币,第 $i$ 堆金币的总重量和总价值分别是 mi​,vi​(1≤mi​,vi​≤100)。阿里巴巴有一个承重量为 T(T≤1000)的背包,但并不一定有办法将全部的金币都装进去。他想装走尽可能多价值的金币。所有金币都可以随意分割,分割完的金币重量价值比(也就是单位价格)不变。请问阿里巴巴最多可以拿走多少价值的金币?

 输入格式

第一行两个整数 N,T。

接下来 N 行,每行两个整数 mi​,vi​。

输出格式

一个实数表示答案,输出两位小数

样例输入 

4 50
10 60
20 100
30 120
15 45

样例输出 

240.00

总结如下:

这是一个经典的背包问题,可以使用动态规划算法来解决。

首先,我们定义一个二维数组 dp,其中 dp[i][j] 表示在前 i 堆金币中,背包容量为 j 时能够获取的最大价值。

然后,我们可以使用以下递推关系式来计算 dp[i][j]:

当 i=0 或 j=0 时,dp[i][j] = 0,表示没有金币或背包容量为 0,无法获取任何价值。
当 j < mi 时,dp[i][j] = dp[i-1][j],表示当前背包容量无法容纳第 i 堆金币,所以最大价值与前 i-1 堆金币的最大价值相同。
当 j ≥ mi 时,dp[i][j] = max(dp[i-1][j], dp[i-1][j-mi] + vi),表示可以选择装入第 i 堆金币或不装入第 i 堆金币,取两者中的最大值作为最大价值。
最后,dp[N][T] 就是阿里巴巴最多可以拿走的金币的最大价值。

代码如下:

#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
#include<iostream>
using namespace std;
int n, t;
struct node {
	int w;
	int v;
}a[110];
double s;
bool cmp(node& a, node& b) {
	return a.v * b.w > b.v * a.w;
}
int main() {
	cin >> n >> t;
	for (int i = 1; i <= n; i++)
		cin >> a[i].w >> a[i].v;
	sort(a + 1, a + 1 + n, cmp);
	for (int i = 1; i <= n; i++) {
		if (t >= a[i].w) {
			s += a[i].v;
			t -= a[i].w;
		}
		else {
			s += 1.0 * t * a[i].v / a[i].w;
			break;
		}
	}
	printf("%.2lf", s);
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值