【积累】求 和不小于K的连续子数组的最短长度/长度不大于M的连续子数组最大和

杂题:求 和不小于K的连续子数组的最短长度/长度不大于M的连续子数组最大和

862. 和至少为 K 的最短子数组

题意:

给定一个长度为 \(n\) 的数组 \(A\)\(-10^5\leq A_i\leq10^5\),要求出 和不小于 \(K\) 的连续子数组的最短长度。

解:

无非是双指针,右指针一直往右扫,左指针在适当的时候右移

\(sum=0\) 时,设置左指针为当前位置的下一位置;

\(sum>=K\) 时,加一些判断,使左指针适当右移。

之前做过一样的题,但是卡在了左指针右移上,一直处理不好。然后这次遇上了还是不会T^T。看了题解,记下来吧。

代码:

#include<bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
#define mkp(a,b) make_pair(a,b)
using namespace std;
const int mod=998244353;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int maxn=1e6+5;
int n,lim;ll a[maxn];
int solve()
{
    int sum=0,st=1,res=inf;
    for(int i=1;i<=n;i++)
    {
        if(a[i]>=lim)return 1;
        sum+=a[i];
        if(sum<=0){
            sum=0;
            st=i+1;
            continue;
        }
        for(int j=i-1;a[j+1]<0;j--){
            a[j]+=a[j+1];
            a[j+1]=0;
        }//!!!!!!!!
        if(sum>=lim){
            while(sum-a[st]>=lim||a[st]<=0)sum-=a[st++];
            res=min(res,i-st+1);
        }
    }
    return res==inf?-1:res;
}
int main()
{
    scanf("%d%d",&n,&lim);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    printf("%d\n",solve());
}

P1714 切蛋糕

题意:

给定一个长度为 \(n\) 的数组 \(A\)\(-500\leq A_i\leq500\),要求出 。长度不大于 \(M\) 的连续子数组的最大和。

解:

代码:

#include<bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
#define mkp(a,b) make_pair(a,b)
using namespace std;
typedef long long ll;
const int maxn=1e6+2;
const int mod=1e9+7;

int a[maxn];
int main()
{
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)scanf("%d",&a[i]);
	int sum=0,st=1,res=0;
	for(int i=1;i<=n;i++)
	{
		sum+=a[i];
		if(sum<=0){
			sum=0;st=i+1;
			continue;
		}
		for(int j=i-1;a[j+1]<0;j--){
			a[j]+=a[j+1];
			a[j+1]=0;
		}
		while(i-st+1>m||a[st]<=0)sum-=a[st++];
		res=max(res,sum);
	}
	printf("%d\n",res);
}
posted @ 2020-09-18 13:41  草丛怪  阅读(349)  评论(0编辑  收藏  举报