ACM 木材加工问题

Problem Description

工厂准备使用机器加工一批木材 。 每根木材有两个参数 l 和 w , 即木材的长度和木材的重量 。 由于只有一台机器 , 所以木材只能一次加工一根 。在加工每根机器前,需要设置一下机器,这需要花费一定的时间,我们称为设置时间。设置时间可以按如下方法计算:
( 1 )机器加工第一根木材时,需要 1分钟的设置时间;
( 2 )加工完一根木材 ( 参数为 l 和 w ) 后 , 如果下一根要加工的木材的参数 l ’与 w ’满足 l<=l ’ 与 w<=w ’,则不需要重新设置即可加工,即设置时间为 0 ;否则需要 1 分钟的设置时间。

Input

第一行包含 1个整数N(1<=N<=5000),表示要加工木材的数量。接下来有 2* N个整数l1 w1 l2 w2 …… ,表示每根木材的长度与重量。
例如:如果有一批木材有 5 根 ,每根的长度和重量分别为 :( 9 ,4 )、( 2 , 5 )、( 1 , 2 )、( 5 , 3 )、( 4 , 1 ), 按 (1 , 2) 、 (2 , 5) 、 (4 , 1) 、 (5 , 3) 、 (9 , 4) 的顺序加工可以达到最少的设置时间 2 分钟

Output

输出一个整数,表示加工完这批木材,至少需要多少分钟的加工时间。

Sample Input

5
9 4 
2 5
1 2
5 3 
4 1

Sample Output

2

思考:此题在于求最少加工时间,加工时间 = 机器设置时间+机器工作时间。但对于这个题目来说,机器的加工时间是很短的,不考虑的,因此这个题目也就是变成了求最小的机器设置次数。第一次加工需要设置1次,当下一次的木材的长度和宽度均大于等于正在加工的木材的长度和宽度时就不用重新设置。因此此题是一道很经典的贪心算法的题目。讲木材进行排序,然后遍历即可,需要注意的地方就是,有 (1,3),(1,5),(2,3),(2,4)的情况,所以应该标记每一根木材有没有被加工。

程序说明:我是采用结构体去保存单一木材信息。然后采用sort函数进行排序。

程序:

#include<bits/stdc++.h>
#define maxx 5001
using namespace std;
struct stu
{
   int l, w;
   bool tp;	// 用来标记木材有没有被加工
};


struct stu num[5000];

bool cmp(struct stu a, struct stu b) //长度从小到大,相同重量从小到大
{
	if(a.l == b.l)     
	return a.w < b.w ;
	else return a.l < b.l;
}

int main()
{
	//freopen("in.txt","r",stdin);
	int n, i, mx, x, y, t, sum,  j;

	while(cin >> n)
	{
	
		t = 0;
		memset(num, 0 ,sizeof(num));
		for(i = 0; i < n; i++)
		{
			cin >> num[i].l >> num[i].w;
			num[i].tp = 0;
	    }
	  sort(num, num+n,cmp);
	  sum = 0;
	  int  wx;
	  
	  for(i = 0; i < n; i++)
	  {
	  	if(!num[i].tp)      //如果没有被加工,则开始加工
	  	{
	  	   wx = num[i].w;sum++;
	  		num[i].tp = 1;         //标记为已加工
	  		for(j = i+1; j < n; j++)
	  			if(num[j].w >= wx && !num[j].tp) 	
			  	{
			  		num[j].tp = 1;   //标记为已加工
			  		 wx = num[j].w;
				}	
		}
	  	
	  }
	  cout << sum << endl;
	}
	fclose(stdin);
	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_38736000/article/details/81108825