经典的最长上升子序列:O(m*m) ---> O(m*logm)
#include<iostream>
#include<algorithm>
using namespace std;
int cases;
struct Node
{
int L,W;
bool operator<(const Node &node) const
{
if(L!=node.L)
return (L<node.L);
else
return (W<node.W);
}
};
Node nodes[5001];
int res[5001];
int n;
int maxnum;
void TheLongestDec()
{
int i,j;
for(i=1;i<n;i++)
{
for(j=0;j<i;j++)
{
if(nodes[j].W>nodes[i].W && res[j]+1>res[i])
{
res[i]=res[j]+1;
if(res[i]>maxnum)
maxnum=res[i];
}
}
}
}
int main()
{
cin>>cases;
for(int now=1;now<=cases;now++)
{
cin>>n;
int i;
maxnum=1;
for(i=0;i<n;i++)
{
cin>>nodes[i].L>>nodes[i].W;
}
sort(nodes,nodes+n);
fill(res,res+n,1);
TheLongestDec();
cout<<maxnum<<endl;
// for(i=0;i<n;i++)
// {
// cout<<nodes[i].L<<" "<<nodes[i].W<<endl;
// }
}
return 0;
}
在高效一点,利用二分查找
#include<iostream>
#include<algorithm>
using namespace std;
int cases;
struct Node
{
int L,W;
bool operator<(const Node &node) const
//注意:这里要有const不然提交到zju上会出现编译错误
{
if(L!=node.L)
return (L<node.L);
else
return (W<node.W);
}
};
Node nodes[5001];
int query[5001];
int n;
int top;
void BinarySearch(int key)
//query中已经是递减的,主要思想就是在同样长度的字串中尽量让最后一个元素最大
{
int low=0,high=top;
int mid;
while(low<=high)
{
mid=(low+high)/2;
if(query[mid]>key)
{
low=mid+1;
}
else if(query[mid]<key)
{
high=mid-1;
}
else if(query[mid]==key)
break;
}
if(query[mid]>key)
{
if(query[mid+1]<key)
{
if(query[mid+1]==-1)
top++;
query[mid+1]=key;
}
}
else if(query[mid]<key)
{
query[mid]=key;
}
}
void TheLongestDec()
{
int i;
for(i=0;i<n;i++)
{
BinarySearch(nodes[i].W); //利用二分查找
}
}
int main()
{
cin>>cases;
for(int now=1;now<=cases;now++)
{
cin>>n;
int i;
for(i=0;i<n;i++)
{
cin>>nodes[i].L>>nodes[i].W;
}
sort(nodes,nodes+n);
top=0;
fill(query,query+n,-1);
query[0]=100000;
TheLongestDec();
cout<<top<<endl;
}
return 0;
}