第1部分 基础算法(提高篇)--第1章- 贪心算法1428:数列分段
程序员文章站
2024-03-19 22:01:58
...
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;
}