第四章 贪心算法

4.1 活动安排问题

分析:按照结束时间非递减排序,再贪心。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int NM=105;
bool x[NM];
struct Node{
	int s,f;
}q[NM];

bool comp(struct Node A,struct Node B){
	return A.f<B.f;
}

int Greed(int n)
{
	int i,res,temp;
	x[0]=true;
	res=1;temp=q[0].f;
	for(i=1;i<n;i++){
		if(q[i].s>=temp){
			temp=q[i].f;x[i]=true;res++;
		}
		else x[i]=false;
	}
	return res;
}

int main()
{
	int i,n;
	while(scanf("%d",&n) && n){
		for(i=0;i<n;i++){
			scanf("%d%d",&q[i].s,&q[i].f);
		}
		sort(q,q+n,comp);
		printf("%d\n",Greed(n));
		for(i=0;i<n;i++) if(x[i]) printf("%d ",i);
		printf("\n");
	}
	return 0;
}
/*
11
1 4 
3 5
5 7
0 6
3 8
5 9
8 11
6 10
8 12
2 13
12 14
*/



4.4 哈弗曼编码

__int64 HuffmanTree()
{
	priority_queue<__int64,vector<__int64>,greater<__int64> >pq1;
	__int64 res,t1,t2;
	for(int i=0;i<26;i++){
		if(hash[i]) pq1.push(hash[i]);
	}
	res=0;
	if(pq1.size()==1){
		res=pq1.top();pq1.pop();
	}
	while(pq1.size()>1){
		t1=pq1.top();pq1.pop();
		t2=pq1.top();pq1.pop();
		res+=t1+t2;
		pq1.push(t1+t2);
	}
	return res;
}



4.5 单元最短路径

#include <iostream>
#include <cstdio>
#include <cstring>
//#include <queue>
using namespace std;

const int NM=1005;
const int MAX=0xfffffff;
int a[NM][NM],p[NM],dis[NM],n;
bool vis[NM];

void Dijkstra(int s)
{
	int i,j,mmin,u;
	memset(vis,0,sizeof(vis));
	for(i=1;i<=n;i++){ 
		dis[i]=a[s][i];
		if(dis[i]==MAX) p[i]=0;
		else p[i]=s;
	}
	dis[s]=0;p[s]=0;vis[s]=true;
	for(j=1;j<n;j++)
	{
		mmin=MAX;u=s;
		for(i=1;i<=n;i++)
			if(!vis[i] && dis[i]<mmin){
				mmin=dis[i];u=i;
			}
			if(mmin==MAX) break;
			vis[u]=true;
			for(i=1;i<=n;i++){
				if(!vis[i] && dis[u]+a[u][i]<dis[i]){
					dis[i]=dis[u]+a[u][i];p[i]=u;
				}
			}
	}
}

int main()
{
	int m,s,i,j,x,y,vau;
	while(~scanf("%d%d%d",&n,&m,&s)){
		for(i=1;i<=n;i++){  //初始化
			dis[i]=MAX;
			for(j=1;j<=n;j++)
				a[i][j]=MAX;
		}
		for(i=0;i<m;i++){
			scanf("%d%d%d",&x,&y,&vau);  //单向
			if(vau<a[x][y]) a[x][y]=vau;  //防重边
		}
		Dijkstra(s);
		for(i=1;i<=n;i++){
			printf("%d-%d Mincost:",s,i);
			if(dis[i]<MAX){
				printf("%d\n%d ",dis[i],i);
				j=i;
				while(p[j]!=0){
					printf("%d ",p[j]);j=p[j];
				}
				printf("\n");
			}
			else printf("-1");
		}
	}
	return 0;
}
/*
5 7 1
1 2 10
1 4 30
1 5 100
2 3 50
3 5 10
4 3 20
4 5 60
*/



4.7 多机调度问题

分析:处理时间从大到小排序,然后依此顺序将作业分配给空闲的处理机。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;

const int NM=105;

int main()
{
	int n,m,i,j,t,a[NM];
	while(~scanf("%d%d",&n,&m)){
		priority_queue<int,vector<int>,greater<int> >pq1;
		for(i=0;i<n;i++) scanf("%d",&a[i]);
		sort(a,a+n);
		if(n<m){
			printf("%d\n",a[n-1]);
			continue;
		}
		for(j=1;j<=m;j++) pq1.push(a[n-j]);
		for(i=j;i<=n;i++){
			t=pq1.top();pq1.pop();
			t+=a[n-i];
			pq1.push(t);
		}
		while(!pq1.empty()){
			t=pq1.top();
			pq1.pop();
		}
		printf("%d\n",t);
	}
return 0;
}
/*
7 3
2 14 4 16 6 5 3
*/



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值