第1部分 基礎算法(提高篇)--第1章- 貪心算法1428:數列分段

1428:數列分段

時間限制: 1000 ms 內存限制: 65536 KB
提交數: 1193 通過數: 733
【題目描述】
對於給定的一個長度爲N的正整數數列A[i],現要將其分成連續的若干段,並且每段和不超過M(可以等於M),問最少能將其分成多少段使得滿足要求。

【輸入】
第1行包含兩個正整數N,M,表示了數列A[i]的長度與每段和的最大值;

第2行包含N個空格隔開的非負整數A[i],如題目所述。

【輸出】
一個正整數,輸出最少劃分的段數。

【輸入樣例】
5 6
4 2 4 5 1
【輸出樣例】
3
【提示】
【數據範圍】

對於20%的數據,有N≤10;

對於40%的數據,有N≤1000;

對於100%的數據,有N≤100000,M≤109,M大於所有數的最小值,A[i]之和不超過109。


思路:題目不可以打亂順序,原數列是[ 4 2 4 5 1 ],劃分爲三段吼是 [ 4 2 ][ 4 ][ 5 1 ],我們先從第一個開始,當前狀態標記爲 b ,一開始,b=a[1],那麼接下來從2開始枚舉到n,如果當前狀態加上一個數字仍然不超過最大限度m 的話,那就把這個數字加入當前狀態,也就是不再開一個段數,否則就要新開一段了,同時重置狀態s=a[ i ],最後ans要自加,因爲一開始的第一個沒有算進去.

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m,ans,b;
int a[100001];
int main(){
	scanf("%d%d",&n,&m);
	for(int i = 1; i <=n;i++)
	scanf("%d",&a[i]);
	b = a[n];
	for(int i = n - 1; i >= 1; i--)
	{
		if(b + a[i] <= m)//不超過最大限度m 的話,那就把這個數字加入當前狀態
		b += a[i];
		else//新開一段了,同時重置狀態b=a[ i ],ans要自加;
		{
			ans++;
			b = a[i];
		}
	}
	ans++;
	printf("%d",ans);
	return 0;
} 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章