poj 2751 双机调度问题Johnson算法(贪心)

题意:

2台机器,n件任务,每件任务必须先在S1上做,再在S2上做。任务之间先做后做任意。求最早的完工时间。

分析:

这是一个经典问题:2台机器的情况下有多项式算法(Johnson算法),3台或以上的机器是NP-hard的。Johnson算法思想就是贪心,时间复杂度是O(nlogn) 。Johnson算法:   (1) 把作业按工序加工时间分成两个子集,第一个集合中在S1上做的时间比在S2上少,其它的作业放到第二个集合。先完成第一个集合里面的作业,再完成第二个集合里的作业。  (2) 对于第一个集合,其中的作业顺序是按在S1上的时间的不减排列;对于第二个集合,其中的作业顺序是按在S2上的时间的不增排列。

代码:

//poj 2751
//sep9
#include <iostream>
#include <algorithm>
using namespace std;
const int maxN=10024;
struct NODE{
	int x,y;
}a[maxN],b[maxN];
int cmp1(NODE p,NODE q)
{
	return p.x<q.x;
}

int cmp2(NODE p,NODE q)
{
	return p.y>q.y;
}
int s1_finish_time[maxN];

int main()
{
	int n;
	while(scanf("%d",&n)==1&&n){
		int len1=0,len2=0;
		for(int i=0;i<n;++i){
			int x,y;
			scanf("%d%d",&x,&y);
			if(x<y){
				a[len1].x=x;
				a[len1++].y=y;
			}else{
				b[len2].x=x;
				b[len2++].y=y;
			}
		}
		sort(a,a+len1,cmp1);
		sort(b,b+len2,cmp2);
		for(int i=len1;i<len1+len2;++i)
			a[i]=b[i-len1];
		s1_finish_time[0]=a[0].x;
		for(int i=1;i<n;++i)
			s1_finish_time[i]=s1_finish_time[i-1]+a[i].x;
		int sum=0;
		for(int i=0;i<n;++i){
			if(sum>=s1_finish_time[i])
				sum+=a[i].y;
			else
				sum=s1_finish_time[i]+a[i].y;
		}
		printf("%d\n",sum);
	}
	return 0;
} 
时间: 2024-11-02 23:54:10

poj 2751 双机调度问题Johnson算法(贪心)的相关文章

poj 3069 Saruman&#39;s Army(贪心)

 Saruman's Army Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3446   Accepted: 1752 Description Saruman the White must lead his army along a straight path from Isengard to Helm's Deep. To keep track of his forces, Saruman distributes

[ACM] POJ 3318 Matrix Multiplication (随机化算法)

Matrix Multiplication Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 16118   Accepted: 3485 Description You are given three n × n matrices A, B and C. Does the equation A × B = C hold true? Input The first line of input contains a posit

POJ 3069 Saruman&#39;s Army (贪心)

题目大意:直线上有N个点,点i的位置是Xi,从这N个点中选取若干,给他们加上标记,对每一个点,其距离为R以内的区域内必须有被标记的点.求至少需要多少个点被标记. 题目思路:设最左边的点:点p的坐标为x,那么离其距离为R的点的坐标为(x+R),我们应该标记的点应为坐标最接近且小于等于(x+R)的点p,则此时[x,p+R]范围内点点均被标记.依次进行下去,直到包含所有点为止. #include<stdio.h> #include<queue> #include<iostream&

算法导论——所有点对最短路径:稀疏图Johnson算法

package org.loda.graph; import org.loda.structure.Stack; import org.loda.util.In; /** * * @ClassName: Johnson 时间复杂度:EVlgV * @Description: 稀疏图上的johnson算法,由于稀疏图的数据结构推荐使用邻接链表,所以这里也采用邻接链表,该算法也是给稀疏图使用的,如果是密集图,推荐使用实现较为简单的FloydWashall算法,可以保证V^3的时间复杂度 * * Jo

POJ 3318 Matrix Multiplication(随机化算法)

给你三个矩阵A,B,C.让你判断A*B是否等于C. 随机一组数据,然后判断乘以A,B之后是否与乘C之后相等. 很扯淡的啊,感觉这种算法不严谨啊... Matrix Multiplication Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 16255   Accepted: 3515 Description You are given three n × n matrices A, B and C. Does the e

HDU 4004 The Frog&#39;s Games(基本算法-贪心,搜索-二分)

The Frog's Games Problem Description The annual Games in frogs' kingdom started again. The most famous game is the Ironfrog Triathlon. One test in the Ironfrog Triathlon is jumping. This project requires the frog athletes to jump over the river. The

第25章:所有结点对的最短路径问题—floyd-warshall和Johnson算法

二:Floyd-Warshall算法 该算法适用于边权重可以为负值,但环路权重和不能为负值的图,其运行时间为Θ(V3). 假设dkij为从结点i到结点j的所有中间结点全部取自集合{1,2,-,k}的一条最短路径权重.当k=0时,从结点i到结点j的一条不包括编号大于0的中间结点的路径将没有任何中间结点.这样的路径最多只有一条边,因此d(0)ij=wij.因此如果k=0,dkij=wij,若k>=1,则dkij=min(d(k?1)ij,d(k?1)ik+d(k?1)kj). 另外,我们可以在计算最

POJ 3069 Saruman&#39;s Army (简单贪心)

Saruman's Army Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5343   Accepted: 2733 Description Saruman the White must lead his army along a straight path from Isengard to Helm's Deep. To keep track of his forces, Saruman distributes se

POJ 3264 RMQ Spare Table算法

今天下午大帝讲的,我以前也不懂,所以也就跟着学学了,把中间的那个状态转移方程学错了好几次,于是就wa了 好几发. #include<iostream> #include<cstdio> #include<algorithm> #define maxn 200010 using namespace std; int a[maxn],m,n,b[maxn],fl[maxn][50],fr[maxn][50]; void solve() { b[1]=0;//其实就是用来计算