1. 程式人生 > >貪心演算法-求區間至少連續k的最大和

貪心演算法-求區間至少連續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;
}