6309. 完全背包 贪心性价比 +dp

6309. 完全背包 
(File IO): input:backpack.in output:backpack.out

Time Limits: 1000 ms  Memory Limits: 262144 KB  Detailed Limits  

Description

Input

Output

Sample Input

Sample 1:
2 15
3 2
5 3

Sample 2:
3 70
71 100
69 1
1 2
 

Sample Output

Sample 1:
10

Sample 2:
140
 

Data Constraint

Source / Author: backpack

 

题解:

把物品按性价比排序 ,尽量取性价比高的。(AC只限此题)

这种方法是个水法 ,但对完全背包一类问题的正确率可以达到90percent。

为什么正确率能这么高 ?

 可以发现 , 一个性价比高的物品 , 在完全背包问题中 , 优势可以变得很大(买很多) ,当背包容量很大时便更显示出其优势。

10percent是什么情况?

比如现在背包容量为16 , 物品有6种:

代价 : 贡献:

10        3
2          3
3          5
4          5
6          4
4          3

根据性价比排序后 , 排在第一位的是第3件物品,根据90per的贪心 , 我们尽量选他 , 于是选了5个,得到了25的贡献 , 剩下1容量:很浪费,什么也干不了。

但是,我们可以只选4个3物品 , 贡献为20 , 剩余容量4 , 然后再买两个2物品,20+6 = 26 >25!!!

这就是贪心错的原因了 。

 

附上dp:(注意最终不能只取f[m],有可能m不能刚好取到)

	mem(f,128);
	f[0]=0;
	for(int i=1;i<=n;i++) for(int j=0;j<=m;j++) (j - a[i]>=0) && (f[j] = max(f[j] , f[j - a[i]] + b[i]));
	for(int i=0;i<=m;i++) ans = max(ans , f[i]);
	return ;

 

附上贪心:

in(m) , in(n);
	for(ll i=1;i<=n;i++) in(a[i]) , in(b[i]);
	for(ll i=1;i<=n;i++) c[i] = (node){(double) b[i] / a[i] , i};
	sort(c+1,c+1+n ,cmpnode);
	for(ll i=1;i<=n;i++)
	{
		ll can = m / a[c[i].id];
		ans+=b[c[i].id] * can;
		m-=a[c[i].id] * can;
		if(m==0) break;
		printf("%d\n" , c[i].id);
	}
	printf("%lld",ans);


 

 

 

 

 

 

 

 

 

### 完全背包问题中的贪心算法 对于完全背包问题,贪心算法并不是最理想的解决方案。然而,在某些特定条件下,贪心方法仍然能够提供有效的近似解。 #### 价值重量比的选择标准 为了应用贪心策略,通常会先计算每个物品的价值重量比 \( \frac{P_i}{W_i} \),并依据这个比率对所有物品进行降序排列[^2]。这一过程确保了优先考虑单位重量下能带来最高收益的物品。 #### 处理无限数量相同类型的物品 不同于0/1背包问题,完全背包允许每种类型的物品有无限多个副本可供选择。因此,在遍历排序后的列表时,如果当前剩余容量足以容纳更多份同一项,则应尽可能多地加入这些项目直至达到容量上限或无法再增加为止[^3]。 ```cpp // C++ code snippet demonstrating greedy approach for unbounded knapsack problem. #include <vector> using namespace std; struct Item { int weight; double value; }; double fractionalKnapsack(int capacity, vector<Item>& items) { // Calculate the ratio of value to weight and sort by this ratio in descending order for (auto& item : items) { item.value /= item.weight; // Compute value per unit weight } sort(items.begin(), items.end(), [](const Item &a, const Item &b){ return a.value > b.value; }); double totalValue = 0.0; for (const auto& item : items) { if (capacity >= item.weight) { capacity -= item.weight; totalValue += item.value * item.weight; } else { // Add as much fractionally as possible when reaching limit totalValue += item.value * capacity; break; } } return totalValue; } ``` 尽管上述代码展示了如何利用贪心原则处理部分背包情况下的最大化总价值问题,但对于完全背包而言,这种方法并不能保证总是获得全局最优解。这是因为贪心决策仅关注局部利益而忽略了整体结构的影响[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值