O(n*lgn)最长递增子序列实现杭电-1025
基本思想同O(n*n)最长递增子序列实现杭电-1025,但是对其做了改进:
通过一个数组B动态存储长度为i的最长子序列的最小后缀值,并且保证B数组是递增的,B(s)=Ai,s=L(i),需注意一点的是同一长度的
最长子序列会被覆盖,而取代的是 Ai更小的后缀值。
这样在计算L(j)就可通过二分法从B中快速查找第一个满足B(s)<Aj的最大的s,那么L(j)=s+1,同时修正B(s+1)=Aj
该算法的复杂度为O(nlgn),可以AC
#include <stdio.h>
#include <malloc.h>
#include <cstring>
typedef struct
{
int d[3];
}Road;
Road *rs;
void SwapDepth(Road rs[],int s,int e,int dim)
{
int maxindex;
int c=s;
Road temp;
while(c<e)
{
maxindex=c;
if(2*c+2<e && rs[maxindex].d[dim]<rs[2*c+2].d[dim])
maxindex=2*c+2;
if(2*c+1<e && rs[maxindex].d[dim]<rs[2*c+1].d[dim])
maxindex=2*c+1;
if(maxindex != c)
{
temp = rs[c];
rs[c] = rs[maxindex];
rs[maxindex] = temp;
c=maxindex;
}
else
break;
}
}
void CreateHeap(Road rs[],int n,int dim)
{
for(int i=n/2-1;i>=0;--i)
SwapDepth(rs,i,n,dim);
}
void SortHeap(Road rs[],int n,int dim)
{
CreateHeap(rs,n,dim);
Road temp;
for(int i=n-1;i>0;--i)
{
temp = rs[0];
rs[0] = rs[i];
rs[i] = temp;
SwapDepth(rs,0,i,dim);
}
}
void InsertValue(Road rs[],int n,Road value)
{
int p=n/2-1,cur;
++n;
rs[n-1]=value;
while(p>=0)
{
if(rs[p].d[2]<rs[cur].d[2])
{
value=rs[cur];
rs[cur]=rs[p];
rs[p]=value;
cur=p;
p=p/2-1;
}
else
break;
}
}
int MaximalRoads(Road rs[],int n)
{
int length=0,l,r,m=0;
Road temp;
SortHeap(rs,n,0);
//dp问题,求最长递增子序列;rs[i].d[2]中存放长度为i+1的最长子串的最小后缀值,{rs[1].d[2],...,rs[i].d[2],...}
//是递增的
for(int i=0;i<n;++i)
{
l=0;
r=length-1;
while(l<=r)
{
m=(l+r)/2;
if(rs[m].d[2]<=rs[i].d[1])
l=m+1;
else
r=m-1;
}
//l表示第一个大于rs[i].d[1]的值的位置
//假设:{rs[0].d[2],...,rs[length-1].d[2]}当前为 1 2 3 4 5,rs[i].d[1]的当前数值为3.5,那么l=3
//即3.5为当前时刻长度为4的最长子串的最小后缀值(比4要小)
rs[l].d[2]=rs[i].d[1];
if(l>=length)++length;
}
return length;
}
void ReadData()
{
int n;
int j=0;
while(scanf("%d",&n)==1 && n)
{
rs = (Road *)malloc(n*sizeof(Road));
if(rs)
{
for(int i=0;i<n;++i)
{
scanf("%d %d",(rs+i)->d,(rs+i)->d+1);
((rs+i)->d)[2]=0;
}
int roadsnum=MaximalRoads(rs,n);
if (roadsnum==1)
printf("Case %d:\nMy king, at most %d road can be built.\n\n",++j,roadsnum);
else
printf("Case %d:\nMy king, at most %d roads can be built.\n\n",++j,roadsnum);
free(rs);
rs=NULL;
}
}
}
int main()
{
ReadData();
return 0;
}
浙公网安备 33010602011771号