posts - 195,  comments - 30,  trackbacks - 0
题意就是求最长上升子序列,且必须用nlogn的dp算法。

技巧:设置一个数组a[i]

存放所有长度为i的上升子序列中最小的末元素值,比如说只有两个长度为3的上升子序列123和124,那么a[3]中存放的就是3(末元素3<4)

那么当来一个新数data时,如果它的值大于最长长度的末元素的值(即a[ans]),则ans++;且a[ans]=data;

否则,通过二分查找(数组a中的元素为递增),将最接近data且大于data的那个元素更新为data,既最小的大于它的数。
例如1,5,3,4,之后来个2,a[1]=1,a[2]=3,a[3]=4;则更新a[2]=2;
由于二分查找复杂度为log(n),外围为n,总的复杂度为nlogn

代码。
#include <stdio.h>
int res[40000];
int binSearch(int left, int right, int num)//找到最小的大于等于它的数 
{
    
while(left <= right)
    {
        
int mid=(left + right)/2;
         
if(res[mid]<num)
            left
=mid+1;
        
else
            right
=mid-1;
    }
    
return right;
}

int main()
{
 
//freopen("s.txt","r",stdin);
 
// freopen("key.txt","w",stdout);
    int t, n, num;
    scanf(
"%d"&t);
    
while(t--)
    {
        scanf(
"%d %d"&n, &num);
        res[
0]=num;
        
int tot = 1;
        
for(int i=1;i<n;++i)
        {
            scanf(
"%d"&num);
            
if(num>=res[tot-1])
            res[tot
++]=num;
            
else
            {
                
int pos=binSearch(0,tot-1,num);//找到最小的大于它的数 
                res[pos+1= num;
            }   
        }
        printf(
"%d\n", tot);
    }
    
return 0;
}
posted on 2009-07-12 15:46 luis 阅读(504) 评论(0)  编辑 收藏 引用 所属分类: 动态规划

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2009年7月>
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678

常用链接

留言簿(3)

随笔分类

随笔档案

文章分类

文章档案

友情链接

搜索

  •  

最新评论

阅读排行榜

评论排行榜