zoukankan      html  css  js  c++  java
  • 【二分查找+优化O(n)】【续UVA1121】Subsequence

    之前的二分答案做法

    http://blog.csdn.net/zy691357966/article/details/40212215


    二分查找做法:

    我们首先试试只枚举终点。对于终点j,我们的目标是要找到一个让Bj-Bi-1S,且i尽量大(i越大,序列长度j-i+1就越小)的i值,也就是找一个让Bi-1Bj-S最大的i注意到B是递增的(别忘了,本题中所有Ai均为整数),所以可以用二分查找。(如果不是整数的话可以用之前的二分答案做法)


    #include <cstdio>  
    #include <cstdlib>  
    #include <cmath>  
    #include <cstring>  
    #include <ctime>  
    #include <algorithm>  
    #include <iostream>
    #include <sstream>
    #include <string>
    #define oo 0x13131313   
    #define maxn 100000+100
    using namespace std;
    int n,S;
    int A[maxn];
    int ans;
    void input()
    {
    	ans=oo;
    	for(int i=1;i<=n;i++)
    			{
    				scanf("%d",&A[i]);
    				A[i]+=A[i-1];
    			}
    }
    int find(int n)
    {
    	int s=1,e=n,m=0;
    	if(A[n]-A[s-1]<S) return -1;
    	while(s<e)
    	{
    		m=(s+e)/2+1;
    		if(A[n]-A[m-1]>=S)
    		s=m;
    		else 
    		e=m-1;
    	}
    	return s;
    }
    int main()
    {
    	//	freopen("a.in","r",stdin);
    	//	freopen("a.out","w",stdout);
    		int k;
    		while(cin>>n>>S)
    		{
    			input();
    			for(int i=1;i<=n;i++)
    			{
    				k=find(i);
    				if(k!=-1)
    				{
    					ans=min(ans,i-k+1);
    				}
    			}
    				if(ans==oo)
    				ans=0;
    			cout<<ans<<endl;
    		}
    }
      

    继续优化:

    上面代码的时间复杂度是O(nlogn)。可以将其继续优化到O(n)。由于j是递增的,Bj也是递增的,所以Bi-1Bj-S的右边也是递增的。换句话说,满足条件的i的位置也是递增的。因此我们可以写出这样的程序。

    #include <cstdio>  
    #include <cstdlib>  
    #include <cmath>  
    #include <cstring>  
    #include <ctime>  
    #include <algorithm>  
    #include <iostream>
    #include <sstream>
    #include <string>
    #define oo 0x13131313 
    #define maxn 100000+100  
    using namespace std;
    int n,S;
    int A[maxn];
    int ans;
    void input()
    {
    	ans=oo;
    	for(int i=1;i<=n;i++)
    			{
    				scanf("%d",&A[i]);
    				A[i]+=A[i-1];
    			}
    }
    int main()
    {
    	freopen("a.in","r",stdin);
    	freopen("a.out","w",stdout);
    	while(cin>>n>>S)
    	{
    		int i=1;
    		input();
    		for(int j=1;j<=n;j++)
    		{
    			if(A[j]-A[i-1]>=S)
    			{
    				while(A[j]-A[i-1]>=S&&i<=j)
    				{
    					ans=min(ans,j-i+1);
    					i++;
    				}
    			}
    		}
    		if(ans==oo) ans=0;
    		cout<<ans<<endl;
    	}
    }
      


  • 相关阅读:
    【python系列】安装完PyCharm创建项目提示No Python interpreter selected
    银联支付测试
    【linux系列】linux防火墙的关闭开启
    【linux系列】vmware12pro安装centos7
    【linux系列】安装虚拟机时候的3中网络模式
    JavaBean与Map<String,Object>相互转换
    【CSS系列】布局篇
    【CSS系列】对表单和数据表格应用样式
    【CSS系列】图像映射
    【Linux系列】find命令使用
  • 原文地址:https://www.cnblogs.com/zy691357966/p/5480446.html
Copyright © 2011-2022 走看看