高效(防线,uva 1471)

本文介绍了一种使用二分搜索优化的高效算法实现方法,并通过具体的代码示例详细展示了如何利用该技巧来替代暴力枚举和低效的set操作,从而显著提高算法执行效率。

参考 http://blog.youkuaiyun.com/L123012013048/article/details/45054857


一开始用set弄,erase弄超时了。

后半部分的方法十分不错。

一方面思路用二分搜索代替了暴力枚举。

另一方面,这种技巧有时能代替低效的set,大大提高效率,今后解题都可以参考。

前面的滑窗也有许多小细节需要处理。


#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;

int MIN[200010];

int main()
{
    int Z;
    scanf("%d",&Z);
    while(Z--)
    {
        vector<int>vec;
        vector<int>f;
        vector<int>g;
        int temp;
        int n;
        scanf("%d",&n);
        for(int i=0;i<n;i++)
        {
            scanf("%d",&temp);
            vec.push_back(temp);
        }
        f.resize(vec.size());
        g.resize(vec.size());
        int l,r;
        l=r=0;
        while(1)
        {
            while(r<n)
            {
                g[r]=r-l+1;
                if(l==r) r++;
                else if(vec[r]>vec[r-1]) r++;
                else break;
            }
            f[l]=r-l;
            l++;
            if(l==r&&r==n)
                break;
        }
        /*for(int i=0;i<n;i++)
            printf("%d ",f[i]);
        puts("");
        for(int i=0;i<n;i++)
            printf("%d ",g[i]);
        puts("");*/
        int ans=1;
        memset(MIN,0X3F,sizeof(MIN));
        for(int i=0;i<n;i++)
        {
            int len=lower_bound(MIN+1,MIN+n+1,vec[i])-MIN;
            ans=max(ans,len+f[i]-1);
            MIN[g[i]]=min(MIN[g[i]],vec[i]);
        }
        printf("%d\n",ans);
    }
    return 0;
}

#include<bits/stdc++.h>
#define maxn 200010
using namespace std;

int l[maxn];
int r[maxn];
int A[maxn];
int n;
int MIN[maxn];

int main()
{
    int Z;
    scanf("%d",&Z);
    while(Z--)
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%d",&A[i]);
        int L,R;
        L=R=1;
        while(L<=n||R<=n)
        {
            while(R<=n&&A[R]>A[R-1])
            {
                l[R]=R-L+1;
                R++;
            }
            while(L<R)
            {
                r[L]=R-L;
                L++;
            }
            l[R]=1;
            R++;
        }
        /*for(int i=1;i<=n;i++)
            printf("%d ",l[i]);
        puts("");
        for(int i=1;i<=n;i++)
            printf("%d ",r[i]);
        puts("");*/
        int ans=1;
        memset(MIN,0X3F,sizeof(MIN));
        for(int i=1;i<=n;i++)
        {
            int k=lower_bound(MIN+1,MIN+1+n,A[i])-MIN-1;
            ans=max(ans,r[i]+k);
            MIN[l[i]]=min(MIN[l[i]],A[i]);
        }
        printf("%d\n",ans);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值