贪心: 每一步行动总是按某种指标选取最优的操作来进行, 该指标只看眼前,并不考虑以后可能造成的影响。
圣诞节来临了,圣诞老人准备分发糖果,现
在有多箱不同的糖果,每箱糖果有自己的价值和重
量,每箱糖果都可以拆分成任意散装组合带走。圣
诞老人的驯鹿雪橇最多只能装下重量W的糖果,请
问圣诞老人最多能带走多大价值的糖果。
#include<iostream>
#include<algorithm>
#include<memory.h>
#include<iomanip>
const double eps = 1e-6;
using namespace std;
int W;
double V;
struct suger{
int w;
int v;
bool operator<(const suger& s){
return double(v)/w-double(s.v)/s.w>eps;
}
}sugers[110];
void greedy(int &total,int &n){
for(int i=0;i<n;i++){
if(total+sugers[i].w<=W){
total += sugers[i].w;
V += sugers[i].v;
}
else {
V += sugers[i].v* double(W-total)/sugers[i].w; W = W+W-total;
break;
}
}
}
int main(void)
{
int n,total=0;
cin>>n>>W;
for(int i=0;i<n;i++){
cin>>sugers[i].v>>sugers[i].w;
}
sort(sugers,sugers+n);//自己写
greedy(total,n);
cout<<fixed<<setprecision(1)<<V;
}
各地放了多部电影 ,给定每部电影的放映时间区间,区间重叠的电影不可能同时
看(端点可以重合),问李雷最多可以看多少部电影。
int total;
struct film{
int s;
int e;
bool operator<(const film& f){
return e<f.e;
}
}f,films[110];
int main(void)
{ int n;cin>>n;
for(int i=0;i<n;i++){
cin>>films[i].s>>films[i].e;
}
sort(films,films+n);
total++;f=films[0];
for(int i=1;i<n;i++){
if(f.e<=films[i].s){
total++;
f=films[i];
}
}
cout << endl<<total;
}
有 n头牛(1<=n<=50,000)要挤奶。给定每头牛挤奶的时间区
间[A,B] (1<=A<=B<=1,000,000,A,B为整数)。
牛需要呆畜栏里才能挤奶。一个畜栏同一时间只能容纳一头牛。
问至少需要多少个畜栏,才能完成全部挤奶工作,以及每头牛都
放哪个畜栏里(Special judged)
去同一个畜栏的两头牛,它们挤奶时间区间哪怕只在端点重合也
是不可以的。
//难点:优先队列的运用 + 配合贪心和队列的排序
//(奶牛和栅栏的顺序定义operator,栅栏和奶牛都需要no来记录原顺序编号)
#include<iostream> //(因为它们都被排序打乱了 )
#include<algorithm> //ps:循环均为从1开始
#include<queue>
using namespace std;
struct cow{
int s;//时间区间 start -end
int e;
int no; //奶牛编号:防止原奶牛顺序 由于进入时间的排序而被打乱
operator<(const cow& c){ //排序
return s<c.s;
}
}cows[100];
int pos[100];
typedef struct fence{
int e;//栅栏的结束时间不断在变 ,作为队列排序依据
int no; //栅栏编号,方便记录奶牛进入的栅栏(同样是防止队列顺序更新而失去原顺序编号)
bool operator<(const fence & f) const {
return e > f.e;
}
fence(int e,int n):e(e),no(n){};// 对栅栏赋值。
}fen;
int total; //栅栏数
int main(void)
{ //1.奶牛赋值+排序
int n;cin>>n;
for(int i=1;i<=n;i++){
cin>>cows[i].s>>cows[i].e;
cows[i].no=i;//排序前,在赋值no过程记录好原位置
}
sort(cows+1,cows+n+1);
//2.栅栏赋值+排序
priority_queue<fen> pq;
for(int i=1;i<=n;i++){
if(pq.empty()){//情况1.最开始(无奶牛)
++total;
pq.push(fen(cows[i].e,total));
pos[cows[i].no]=total;
}
else { //情况2. next奶牛与目前栅栏冲突
fen f=pq.top();//利用排序(目前结束最快) 找到待命栅栏
if(f.e>=cows[i].s){
++total;
pq.push(fen(cows[i].e,total)); //冲突加入新栅栏,编号即total
pos[cows[i].no]=total;
}
else {//情况3. 不冲突
//不冲突:total不变,队列弹出原奶牛,压入新奶牛
pq.pop();
pos[cows[i].no]=f.no; //进入编号为top(待命)的栅栏
pq.push(fen(cows[i].e,f.no)); //不冲突使用原栅栏
}
}
}
//3.循环结束,事件结束,输出
cout<< total<<endl;
for(int i=1;i<=n;i++)
cout<<pos[i]<<endl;
}