0
点赞
收藏
分享

微信扫一扫

[做题]贪心算法 20

产品喵dandan米娜 2022-03-23 阅读 46
算法

贪心: 每一步行动总是按某种指标选取最优的操作来进行, 该指标只看眼前,并不考虑以后可能造成的影响。

圣诞节来临了,圣诞老人准备分发糖果,现

在有多箱不同的糖果,每箱糖果有自己的价值和重

量,每箱糖果都可以拆分成任意散装组合带走。圣

诞老人的驯鹿雪橇最多只能装下重量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;
}

举报

相关推荐

0 条评论