贪心算法:
每一步行动总是按某种指标选取最优的操作来进行,该指标只看眼前,并不考虑以后可能造成的影响。(贪心算法需要证明其正确性)
t1.圣诞老人的礼物(百练4110)
思路:
按礼物的价值/重量比从小到大依次选取礼物,对选取的礼物尽可能多装,直到到达总重量w(注意糖果并不是只能整箱装,也可以一颗一颗装)
代码如下:
#include<bits/stdc++.h>//万能头
using namespace std;
const double eps = 1e-6;//定义一个很小的值
struct Candy {
int v;//糖果价格
int w;//糖果重量
bool operator < (const Candy& c) const
//运算符小于,用于比较价值重量比
{
return double(v) / w - double(c.v) / c.w > eps;
}
}candies[110];
int main() {
int n, w;
scanf_s("%d%d", &n, &w);//读入数据
for (int i = 0; i < n; i++)
scanf_s("%d%d", &candies[i].v, &candies[i].w);//读入每箱糖果的价值和重量
sort(candies, candies + n);//按价值重量比来排序
int totalW = 0;//初始化选中的重量为零
double totalV = 0;//初始化选中的总价格为零
for (int i = 0; i <= n; i++) {//按价值重量比从大到小选
if (totalW + candies[i].w <= w) {//判断是否能拿(先整箱拿)
totalW += candies[i].w;
totalV += candies[i].v;
}
else {//不能整箱拿只能从第i箱里拿一部分
totalV += candies[i].v * double(w - totalW) / candies[i].w;//在第i箱糖果里拿糖果
break;
}
}
printf("%.1f", totalV);
return 0;
}
t2.分配畜栏poj3190
思路:
代码如下:
#include <iostream>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;
struct Cow {//奶牛
int a, b;//挤奶区间起点和终点
int No;//编号
bool operator<(const Cow& c)const {//重载小于号
return a < c.a;//按开始时间排序
}
}cows[50100];
int pos[50100];//编号为i的奶牛去的畜栏编号
struct Stall {//畜栏
int end;//结束时间
int No;//编号
bool operator<(const Stall& s)const {//重载小于号
return end > s.end;//畜栏排序的规则,通过优先队列,把最早的畜栏放到队头
}
Stall(int e, int n) :end(e), No(n) { }
};
int main()
{
int n;
scanf_s("%d", &n);
for (int i = 0; i < n; i++) {
scanf_s("%d%d", &cows[i].a, &cows[i].b);
cows[i].No = i;
}
sort(cows, cows + n);
int total = 0;//畜栏总数
priority_queue<Stall> pq;//畜栏的优先队列
for (int i = 0; i < n; i++) {
if (pq.empty()) {
++total;
pq.push(Stall(cows[i].b, total));//结束时间最早的畜栏放队头
pos[cows[i].No] = total;
}
else {
Stall st = pq.top();//取早结束时间的畜栏
if (st.end < cows[i].a) {//判断最早的那个畜栏是否能用(端点也不能重合)
pq.pop();
pos[cows[i].No] = st.No;
pq.push(Stall(cows[i].b, st.No));//放了奶牛后,修改畜栏
}
else {//对应if (st.end < cows[i].a)
//找不到空的畜栏,新建一个畜栏
++total;
pq.push(Stall(cows[i].b, total));
pos[cows[i].No] = total;
}
}
}
printf("%d\n", total);
for (int i = 0; i < n; i++)
printf("%d\n", pos[i]);
return 0;
}
大数据 201 liyang