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;
}

posted on 2011-05-10 16:27  明日之星  阅读(367)  评论(0)    收藏  举报