最大上升子序列算法及其改进

本文探讨了最大上升子序列问题,首先介绍了原始的n^2复杂度算法,随后重点讲解了一种改进方法,利用二分查找动态更新dp[len],从而提高算法效率。
摘要由CSDN通过智能技术生成


这是改进前的算法,算法复杂度是n^2


2.	#include <stdio.h>  
3.	#define  MAX 1000  
4.	int seq[MAX+10];  
5.	int seqlen[MAX+10];  
6.	int main()  
7.	{  
8.	    int i,j,k,N,max,maxlen=1;  
9.	    for(i=1;i<=9;i++)  
10.	        seqlen[i]=1;               //seqlen数组存以第i个数为终点的最长上升序列  
11.	    scanf("%d",&N);  
12.	    for(i=1;i<=N;i++)  
13.	        scanf("%d",&seq[i]);       //seq数组保存序列数组  
14.	    for (i=2;i<=N;i++)  
15.	    {  
16.	        max=0;  
17.	        for (j=1;j<=i-1;j++)  
18.	        {  
19.	            if(seq[j]<seq[i]&&seqlen[j]>max)  //在前i-1个序列中,寻找以终点小于seq[i]的最长的子序列,即最优子状态  
20.	                max=seqlen[j];  
21.	        }  
22.	        seqlen[i]=max+1;  
23.	        if(seqlen[i]>maxlen)           //seqlen中保存的是第i个数为终点的最长上升序列,找出这个数组中最大的值即为最优序列长度  
24.	            maxlen=seqlen[i];  
25.	    }  
26.	    printf("%d/n",maxlen);  
27.	    return 0;  
28.	}  



改进后的算法:

#include <stdio.h>
int city[500005];
int dp[500005];

int binaryseach(int x,int len)
{
    int left,mid,right;
    left=1;
    right=len;
    while(left<=right)
    {
        mid=(right+left)/2;
        if(dp[mid]<x)
        {
            left=mid+1;
        }
        else
        {
            right=mid-1;
        }
    }
    return left;
}

int main()
{
    int i,j;
    int len;
    int r,p;
    int n;
    int casen;
    casen=0;
    while(scanf("%d",&n)!=EOF)
    {
        for(i=1;i<=n;i++)
        {
            scanf("%d%d",&r,&p);
            city[r]=p;
        }
        dp[0]=-1000000;
        dp[1]=city[1];
        len=1;
        for(i=2;i<=n;i++)
        {
            j=binaryseach(city[i],len);
            dp[j]=city[i];
            if(j>len)
            {
                len=j;
            }
        }
        if(len==1)
        {
            printf("Case %d:\nMy king, at most 1 road can be built.\n\n",++casen);
        }
        else
        {
            printf("Case %d:\nMy king, at most %d roads can be built.\n\n",++casen,len);
        }
    }
    return 0;
}

关于优化的思想:

二分查找会动态的更新dp[len]中的数据,二分搜索会在dp[len]中查找city[i]的位置然后替换掉原来的数据。如果不在dp[len]中,那么j就会比len大,所以len++;







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值