zoukankan      html  css  js  c++  java
  • hdu 4604 动态规划

    思路:这题的感觉就是最长上升子序列的升级版。首先对于最长上升子序列要用n*log(n)的算法才行,这个复杂度的算法可以从hdu1025得到启发。然后就是什么情况下最优问题了。对于序列中某个数i,找出其后面最长不下降子序列长度和最长不上升子序列长度,将这两个长度加起来,最大的就是我们要找到。但由于存在相同值,那么我么就要确定这两个子序列中值为i的个数最少的那个,用上面求得和减去它。

    我的代码比较挫。

    #include<iostream>
    #include<cstring>
    #include<cmath>
    #include<string>
    #include<cstdio>
    using namespace std;
    int ans[200010],list[100010],low[100010],more[100010],same[100010];
    int main()
    {
        int t,n,i,j;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d",&n);
            memset(low,0,sizeof(low));
            memset(more,0,sizeof(more));
            memset(same,0,sizeof(same));
            for(i=1;i<=n;i++)
                scanf("%d",&list[i]);
            int len;
            ans[1]=list[n];
            low[n]=1;
            len=1;
            same[n]=1;
            int l,r,mid;
            for(i=n-1;i>=1;i--)
            {
                if(ans[len]>=list[i])
                {
                    ans[++len]=list[i];
                    low[i]=len;
                }
                else
                {
                l=1;
                r=len;
                while(l<=r)
                {
                     mid=(l+r)>>1;
                    if(ans[mid]>=list[i])
                        l=mid+1;
                    else
                        r=mid-1;
                }
                ans[l]=list[i];
                low[i]=l;
                }
                l=1,r=len;
                while(l<=r)
                {
                    mid=(l+r)>>1;
                    if(ans[mid]>list[i])
                        l=mid+1;
                    else
                        r=mid-1;
                }
                same[i]=low[i]-r;
            }
            ans[1]=list[n];
            len=1;
            more[n]=1;
            for(i=n-1;i>=1;i--)
            {
                if(ans[len]<=list[i])
                {
                    ans[++len]=list[i];
                    more[i]=len;
                }
                else
                {
                l=1;
                r=len;
                while(l<=r)
                {
                     mid=(l+r)>>1;
                    if(ans[mid]<=list[i])
                        l=mid+1;
                    else
                        r=mid-1;
                }
                ans[l]=list[i];
                more[i]=l;
                }
                l=1,r=len;
                while(l<=r)
                {
                    mid=(l+r)>>1;
                    if(ans[mid]<list[i])
                        l=mid+1;
                    else
                        r=mid-1;
                }
                same[i]=min(more[i]-r,same[i]);
            }
            int Ans=0;
            for(i=1;i<=n;i++)
                Ans=max(Ans,low[i]+more[i]-same[i]);
            printf("%d
    ",Ans);
        }
        return 0;
    }
  • 相关阅读:
    Java中的集合Queue
    CountDownTimer
    CountDownTimer
    CountDownTimer
    CountDownTimer
    【10月新版】Aspose.Pdf 10月新版V17.10发布 | 附下载
    【10月新版】Aspose.Pdf 10月新版V17.10发布 | 附下载
    【10月新版】Aspose.Pdf 10月新版V17.10发布 | 附下载
    【10月新版】Aspose.Pdf 10月新版V17.10发布 | 附下载
    什么是区块链 Layer 0 扩容
  • 原文地址:https://www.cnblogs.com/wangfang20/p/3209536.html
Copyright © 2011-2022 走看看