Time Limit: 1 second
Memory Limit: 128 MB
【问题描述】
对于给定的一个长度为N的正整数数列A[i],现要将其分成连续的若干段,并且每段和不超过M(可以等于M),问最少能将其分成多少段使得满足要求。
【输入格式】
输入文件divide_a.in的第1行包含两个正整数N,M,表示了数列A[i]的长度与每段和的最大值,第2行包含N个空格隔开的非负整数A[i],如题目所述。
【输出格式】
输出文件divide_a.out仅包含一个正整数,输出最少划分的段数。
【数据规模】
对于20%的数据,有N≤10; 对于40%的数据,有N≤1000; 对于100%的数据,有N≤100000,M≤109,M大于所有数的最小值,A[i]之和不超过109。
Sample Input1
5 6
4 2 4 5 1
Sample Output1
3
【样例说明】
将数列如下划分:
[4][2 4][5 1]
第一段和为4,第2段和为6,第3段和为6均满足和不超过M=6,并可以证明3是最少划分的段数。
【题目链接】:http://noi.qz5z.com/viewtask.asp?id=u101
【题解】
每一段尽量多地放元素就好->能放就放满(因为是连续的,所以也没有说像背包问题那样有后效性);
注意开LL吧。
【完整代码】
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <set>
#include <map>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
#include <vector>
#include <stack>
#include <string>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
typedef pair<int,int> pii;
typedef pair<LL,LL> pll;
void rel(LL &r)
{
r = 0;
char t = getchar();
while (!isdigit(t) && t!='-') t = getchar();
LL sign = 1;
if (t == '-')sign = -1;
while (!isdigit(t)) t = getchar();
while (isdigit(t)) r = r * 10 + t - '0', t = getchar();
r = r*sign;
}
void rei(int &r)
{
r = 0;
char t = getchar();
while (!isdigit(t)&&t!='-') t = getchar();
int sign = 1;
if (t == '-')sign = -1;
while (!isdigit(t)) t = getchar();
while (isdigit(t)) r = r * 10 + t - '0', t = getchar();
r = r*sign;
}
const int MAXN = 1e5+100;
const int dx[5] = {0,1,-1,0,0};
const int dy[5] = {0,0,0,-1,1};
const double pi = acos(-1.0);
int n;
LL m;
LL a[MAXN];
int main()
{
//freopen("F:\\rush.txt","r",stdin);
rei(n);rel(m);
rep1(i,1,n)
rel(a[i]);
int now = 1;LL temp = a[1];
rep1(i,2,n)
if (temp+a[i]>m)
{
temp = a[i];
now++;
}
else
temp+=a[i];
cout << now<<endl;
return 0;
}