POJ3061 Subsequence(二进制前缀和法律+仿真足)

POJ3061 Subsequence(二进制前缀和法律+仿真足)

大家好,又见面了,我是全栈君,今天给大家准备了Idea注册码。

二分法+前缀和法律

满足子序列长度的条件(0,n)之间,sum[x+i]-sum[i]从i元素开始序列长度x和。前缀和可在O(n)的时间内统计

sum[i]的值。再用二分找出满足条件的最小的子序列长度。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<vector>
#include<cmath>
#define ll __int64
#define INF 0x3fffffff
using namespace std;

int sum[100005];
int a[100005];
int n,s;

bool C(int x)
{
    bool flag=false;
    for(int i=0;i<n-x;i++)
    {
        if(sum[x+i]-sum[i]>=s)
        {
            flag=true;
            break;
        }
    }
    if(flag) return true;
    else return false;
}

int solve()
{
    int l=0,r=n+1;
    while(r-l>1)
    {
        int mid=(l+r)/2;
        if(C(mid)) r=mid;
        else l=mid;
    }
    return r;
}

int main()
{
    int T;
    //freopen("d:\\Test.txt","r",stdin);
    cin>>T;
    while(T--)
    {
        cin>>n>>s;
        for(int i=0;i<n;i++)
        {
            scanf("%d",&a[i]);
        }
        sum[0]=a[0];
        for(int i=1;i<n;i++)
        {
            sum[i]=sum[i-1]+a[i];
        }
        if(solve()==n+1) cout<<"0"<<endl;
        else cout<<solve()<<endl;
    }
    return 0;
}

尺取法

(1)  设置两个指针s和t。一開始都指向数列第一个元素。此外sum=0,res=0。

(2)  仅仅要sum<S。就将sum添加一个元素,t加1;

(3)  直到sum>=S,更新res=min(res,t-s);

(4)  将sum减去一个元素。s加1,运行(2)。

上述流程重复地推进区间的开头和末尾,来求取满足条件的最小区间。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m;
int a[100005];

void solve()
{
    int res=n+1;
    int s=0,t=0,sum=0;
    while(true)
    {
        while(t<n&&sum<m)
        {
            sum+=a[t++];
        }
        if(sum<m) break;
        res=min(res,t-s);
        sum-=a[s++];
    }
    if(res>n) res=0;
    cout<<res<<endl;
}

int main()
{
	int T;
    //freopen("d:\\Test.txt","r",stdin);
    cin>>T;
    while(T--)
    {
        cin>>n>>m;
        for(int i=0;i<n;i++)
        {
            scanf("%d",&a[i]);
        }
        solve();
    }
    return 0;
}

版权声明:本文博客原创文章,博客,未经同意,不得转载。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/117508.html原文链接:https://javaforall.net

(0)
上一篇 2022年1月4日 下午6:00
下一篇 2022年1月4日 下午6:00


相关推荐

  • ConcurrentSkipListMap和ConcurrentHashMap

    ConcurrentSkipListMap和ConcurrentHashMapConcurrentSk 使用红黑树按照 key 的顺序 自然顺序 自定义顺序 来使得键值对有序存储 但是只能在单线程下安全使用 多线程下想要使键值对按照 key 的顺序来存储 则需要使用 ConcurrentSk ConcurrentSk 的底层是通过跳表来实现的 跳表是一个链表 但是通过使用 跳跃式 查找的方式使得插入 读取数据时复杂度变成了 O logn 跳表 SkipList 使用 空间换时间 的算法 令链表的每个结点不仅记录 next

    2026年3月17日
    1
  • 奇怪的电梯

    奇怪的电梯奇怪的电梯【问题描述】某栋大楼有一种很奇怪的电梯。大楼的每一层楼都可以停电梯,而且第i层楼(1≤i<N)上有一个数字K(≤K≤N)电梯只有四个按钮:开、关、上、下。上、下的层数等于当前楼层上的那个数字。当然,如果不能满足要求,相应的按钮就会失灵。例如:33125代表了Ki(K1=3,K2=3,…),从一层开始。在一层按“上”可以到4层,按“下”是不起作用的,因为没有-2层。那么从A层到B层至少要按几次按钮呢?【输入格式】第1行为3个用1个空格隔开的正整数,表示N、A、B(l≤N≤200,1≤

    2022年6月14日
    41
  • winhex哈希值校验_文件的哈希值不在指定的目录中

    winhex哈希值校验_文件的哈希值不在指定的目录中Certutil是一个windows预装的CLI程序,主要作用是转储和显示证书颁发机构(CA),配置信息,证书服务,CA组件的备份和还原以及验证证书、密钥对和证书链,它作为证书服务的一部分安装。可用于校验文件MD5、SHA1、SHA256,下载恶意文件和免杀。这里记录如何使用这个程序校验文件,网上很多资源的下载很多都会提供文件的md5,SHA256等等之类的哈希值,便于下载者校验文件是否…

    2025年11月2日
    4
  • Java设计模式之结构型:适配器模式

    Java设计模式之结构型:适配器模式

    2021年10月4日
    36
  • mysql联合主键

    mysql联合主键1、hibernate配置联合主键1.1联合主键的好处:联合主键的好处是不需要因为需要主键而增加一个无用的主键列1.2联合主键的建表语句CREATETABLE`HTTP_TERMINAL_DETAIL_STATISTICS`( `TIME`CHAR(14)NOTNULLCOMMENT’时间’, `TERMINAL_TYPE`VARCHAR(128)NOTNULLCO…

    2022年6月29日
    32

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号