题目地址
题目描述
一堆木头棍子共有n根,每根棍子的长度和宽度都是已知的。棍子可以被一台机器一个接一个地加工。机器处理一根棍子之前需要准备时间。准备时间是这样定义的:
第一根棍子的准备时间为1分钟;
如果刚处理完长度为L,宽度为W的棍子,那么如果下一个棍子长度为Li,宽度为Wi,并且满足L>=Li,W>=Wi,这个棍子就不需要准备时间,否则需要1分钟的准备时间;
计算处理完n根棍子所需要的最短准备时间。比如,你有5根棍子,长度和宽度分别为(4, 9),(5, 2),(2, 1),(3, 5),(1, 4),最短准备时间为2(按(4, 9)、(3, 5)、(1, 4)、(5, 2)、(2, 1)的次序进行加工)。
思路
首先这样一个题目,首先想到使用喜闻乐见的贪心法,再看这一题,如果前一根木棍S相对于下一根木棍Si的属性满足L>=Li,W>=Wi,那么就可以减少木棍加工准备时间。自然会想到利用这两个属性排序,由于两个属性的优先级一样,那么可以按照长度进行排序,当长度相等时再根据宽度排序。
有了这样一个贪心后的数据,接着就是模拟过程,求出答案。
#include <iostream>
#include <algorithm>
using namespace std;
struct Wood
{
int L;
int W;
};
int N;
Wood Stick[5001];
bool cmp1(Wood,Wood);
int Simulation(void);
int main(void)
{
cin >> N;
for(int i = 1;i <= N;i++)
{
cin >> Stick[i].L >> Stick[i].W;
}
int ans = 1;
sort(Stick+1,Stick+N+1,cmp1);
ans = Simulation();
cout << ans << endl;
return 0;
}
int Simulation(void)
{
int ans = 0;
bool Processed[5001] = {0};
int Now = 1;
while(1)
{
ans++;
Processed[Now] = true;
for(int i = 1;i <= N;i++)
{
if(Stick[i].L <= Stick[Now].L && Stick[i].W <= Stick[Now].W && !Processed[i])
{
Processed[i] = true;
Now = i;
}
}
bool Quit = true;
for(int i = 1;i <= N;i++)
{
if(!Processed[i])
{
Now = i;
Quit = false;
break;
}
}
if(Quit)
{
break;
}
}
return ans;
}
bool cmp1(Wood a,Wood b)
{
if(a.L == b.L)
{
return a.W > b.W;
}
return a.L > b.L;
}