HDU 5783 Divide the Sequence(数列划分)

时间:2021-12-02 06:23:18


HDU 5783 Divide the Sequence(数列划分)

Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)

 

Problem Description - 题目描述

Alice has a sequence A, She wants to split A into as much as possible continuous subsequences, satisfying that for each subsequence, every its prefix sum is not small than 0.
Alice有一个数列A,她想把A拆分出尽可能多的子串,并且每个子串的任意前缀和都大于0。

CN

Input - 输入
The input consists of multiple test cases.
Each test case begin with an integer n in a single line.
The next line contains n integers A1,A2⋯An.
1≤n≤1e6
−10000≤A[i]≤10000
You can assume that there is at least one solution.
多组测试用例。
每组测试用例的第一行为一个整数n。
下一行有n个整数A1,A2⋯An。
≤n≤1e6
−≤A[i]≤
你可以认为不存在无解的情况。

CN

Output - 输出

For each test case, output an integer indicates the maximum number of sequence division.
对于每组测试用例,输出此序列的最大划分数。

CN

Sample Input - 输入样例

6
1 2 3 4 5 6
4
1 2 -3 0
5
0 0 0 0 0

Sample Output - 输出样例

6
2
5

题解

  贪心,一开始看错题目了,一直想不出解法,浪费了巨多时间……
  某子串1 2 3的所有前缀为

1
1 2
1 2 3

  显然如果出现负数的话,需要前面的正数来凑,反正无法满足条件。
  做法就是从后往前扫描,记录临时的后n项和,>=0则清空,划分数+1。
  极限数据应该是5e5 * 10000 = 5e9,单纯的int会超,需要__int64。

代码 C++

 #include <cstdio>
__int64 data[];
int main(){
__int64 n, i, opt, tmp;
while (~scanf("%I64d", &n)){
for (i = opt = tmp = ; i < n; ++i) scanf("%I64d", data + i);
for (--i; ~i; --i){
tmp += data[i];
if (tmp >= ) tmp = , ++opt;
}
printf("%I64d\n", opt);
}
return ;
}