贪心算法-求区间至少连续k的最大和

题意:对于一个整数n,表示该区间整数的个数,求至少有k个连续的数是该区间中一段的最大和。

n的范围在1~10^6。k(-1000~1000);

分析:这道题看似有点像树状数组,但要想求出区间至少有k个连续的数的和是最大,恐怕是有点难度,顶多是求某一区间的和。

不过可以沿着这个思路想,sum(n)-sum(i)?。

如果这样想,我们就要判断n-i>=k;那换种思路:在第i的前面寻找最小值,在i+k的后面寻找最大值。这样sum(n)-sum(i)一定是第i个循环中最大的一个。

对于每次这样循环,我只要定义一个变量来接收一个最大值(sum(n)-sum(i))把它与下一个做比较就行了。

思路清晰了,代码应该就好写了。

#include<cstdio>
#include<iostream>
using namespace std;
int n,k;
int a[1000005];
int INF=0x7fffffff;
void maxsum()
   {  
      int l=INF;                              //值最大,能把值传递给l(小于它的值)。
      int r=INF+1;                            //值最小,能把值传递给r(大于它的值)。
     for(int i=k;i<=n;i++)
      {
	    l=l<a[i-k]?l:a[i-k];      //在i-k个前面检测最小的值,每次i++;比较的范围至少相差k个。
        r=r>a[i]-l?r:a[i]-l;      //在i个以后检测最大值。
	 }                           
     cout<<r<<endl; 
}
int main()
{    
    while(scanf("%d%d",&n,&k)!=EOF)
	{
     for(int i=1;i<=n;i++)
     {
       cin>>a[i];
       a[i]+=a[i-1];
     }
	 maxsum();
	}
     return 0;
}
       


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值