【C++】「一本通 1.1 练习 2」数列分段

【来源】

一本通题库-1428
LibreOJ-10006
vjudge

【题目描述】

对于给定的一个长度为 N N N的正整数数列 A [ i ] A[i] A[i],现要将其分成连续的若干段,并且每段和不超过 M M M(可以等于 M M M),问最少能将其分成多少段使得满足要求。

【输入格式】

第1行包含两个正整数 N N N M M M,表示了数列 A [ i ] A[i] A[i]的长度与每段和的最大值;

第2行包含 N N N个空格隔开的非负整数 A [ i ] A[i] A[i],如题目所述。

【输出格式】

一个正整数,输出最少划分的段数。

【输入样例】

5 6 
4 2 4 5 1

【输出样例】

3

【数据范围】

对于 20 20 20%的数据,有 N ≤ 10 N≤10 N10

对于 40 40 40%的数据,有 N ≤ 1000 N≤1000 N1000

对于 100 100 100%的数据,有 N ≤ 100000 N≤100000 N100000 M ≤ 1 0 9 M≤10^9 M109,M大于所有数的最小值, A [ i ] A[i] A[i]之和不超过 1 0 9 10^9 109

【解析】

一题比较简单的贪心。

可以说这是一题模拟题。

  • 判断a[i]的值加起来是否比m大
  • 判断如果加起来比m大,ans++
  • 判断最后的单独一组

就是这么简单。

这里给出了两种写法,都是对的。

【代码1】

#pragma GCC optimize(3,"Ofast","inline")
#pragma G++ optimize(3,"Ofast","inline")

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>

#define RI                 register int
#define re(i,a,b)          for(RI i=a; i<=b; i++)
#define ms(i,a)            memset(a,i,sizeof(a))
#define MAX(a,b)           (((a)>(b)) ? (a):(b))
#define MIN(a,b)           (((a)<(b)) ? (a):(b))

using namespace std;
 
typedef long long LL;

const int N=1e5+5;

int n,m;
int a[N];

int main() {
    scanf("%d%d",&n,&m);
    for(int i=1; i<=n; i++) scanf("%d",&a[i]);
    int sum=0,ans=0;
    for(int i=1; i<=n; i++) {
        if(sum+a[i]>m) {
            sum=a[i];
            ans++;
        } else sum+=a[i];
    }
    if(sum!=0) ans++;
    printf("%d\n",ans);
    return 0;
}

【代码2】

#pragma GCC optimize(3,"Ofast","inline")
#pragma G++ optimize(3,"Ofast","inline")

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>

#define RI                 register int
#define re(i,a,b)          for(RI i=a; i<=b; i++)
#define ms(i,a)            memset(a,i,sizeof(a))
#define MAX(a,b)           (((a)>(b)) ? (a):(b))
#define MIN(a,b)           (((a)<(b)) ? (a):(b))

using namespace std;
 
typedef long long LL;

const int N=1e5+5;

int n,m;
int a[N];

int main() {
    scanf("%d%d",&n,&m);
    for(int i=1; i<=n; i++) scanf("%d",&a[i]);
    int sum=0,ans=1;
    for(int i=1; i<=n; i++) {
        if(sum+a[i]>m) {
            sum=a[i];
            ans++;
        } else sum+=a[i];
    }
    printf("%d\n",ans);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值