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;
}