贪心算法。
将所有需求按l升序,l相同按w升序排序,假设一开始只需要运行一次机器,对第一个需求,一次运行肯定可以满足。对从第二个开始,就要考虑其是否能接到已经运行的机器的尾部,由于排序保证了l升序,即找到当前机器能满足需求且w最大的位置即可,找到该位置之后将当前需求接到机器末尾,同时更新当前机器最大w即可,如果找不到,证明不能接到机器末尾,就要重新开一次机器。
若当前有两个状态的机器w1和w2都能接当前的需求,则肯定接较大的一个,因为对之后的需求,只要较大的能满足,较小的肯定也能满足,而较小的能满足较大的不一定能满足,所以当前接较大的一个肯定是最优解。
附代码:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
struct pp
{
int l,w;
} a[5001];
bool cmp(pp a,pp b)
{
if (a.l!=b.l)
return a.l<b.l;
return a.w<b.w;
}
int main()
{
int T;
cin>>T;
int v[5001];
while (T--)
{
int n;
cin>>n;
for (int i=1;i<=n;i++)
cin>>a[i].l>>a[i].w;
sort(a+1,a+n+1,cmp);
memset(v,0,sizeof(v));
int len=1;
v[1]=a[1].w;
for (int i=2;i<=n;i++)
{
int low=1;
int high=len;
while (low<=high)
{
int m=(low+high)>>1;
if (v[m]>a[i].w)
low=m+1;
else
high=m-1;
}
//cout<<a[i].w<<" "<<v[low]<<endl;
v[low]=a[i].w;
if (low>len)
len=low;
}
cout<<len<<endl;
}
}