贪心算法——部分背包问题
贪心策略的一般步骤:
- 提出贪心策略:观察问题特征,构造贪心选择
- 证明策略正确:假设最优方案,通过替换证明(交换论证法或者数学归纳法)
一、部分背包的形式化定义
贪心策略:最高性价比优先。
先按单位质量的价值从大到小排序,然后尽可能装入单位价值大的物品。
贪心策略正确性证明:
二、伪代码:
三、代码实现:洛谷P2240
#include <iostream>
#include <algorithm>
#include <cstdio>
#define MAXN (100+10)
using namespace std;
struct Node {
int m; // 总重量
int v; // 总价值
double cost_per; //性价比
};
int N,T;
Node node[MAXN];
double tot_value = 0.0;
bool cmp(Node a, Node b)
{
return (a.cost_per - b.cost_per) > 1e-8; //按性价比从大到小排序
}
int main()
{
cin >> N >> T;
for (int i = 0; i < N; ++i) {
cin >> node[i].m >> node[i].v ;
node[i].cost_per = (double)node[i].v / (double)node[i].m;
}
sort(node, node+N, cmp);
for (int i = 0; i < N; ++i) {
if (node[i].m < T) {
tot_value += (double)node[i].v;
T -= node[i].m;
}
else {
tot_value += node[i].cost_per * T;
T = 0;
break;
}
}
printf("%.2lf", tot_value);
return 0;
}