codeforces Round #241(div2) D解题报告

来源:互联网 发布:天知集团李啸天 编辑:程序博客网 时间:2024/04/29 15:25

D. Population Size
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Polycarpus develops an interesting theory about the interrelation of arithmetic progressions with just everything in the world. His current idea is that the population of the capital of Berland changes over time like an arithmetic progression. Well, or like multiple arithmetic progressions.

Polycarpus believes that if he writes out the population of the capital for several consecutive years in the sequence a1, a2, ..., an, then it is convenient to consider the array as several arithmetic progressions, written one after the other. For example, sequence (8, 6, 4, 2, 1, 4, 7, 10, 2) can be considered as a sequence of three arithmetic progressions (8, 6, 4, 2)(1, 4, 7, 10) and (2), which are written one after another.

Unfortunately, Polycarpus may not have all the data for the n consecutive years (a census of the population doesn't occur every year, after all). For this reason, some values of ai ​​may be unknown. Such values are represented by number -1.

For a given sequence a = (a1, a2, ..., an), which consists of positive integers and values ​​-1, find the minimum number of arithmetic progressions Polycarpus needs to get a. To get a, the progressions need to be written down one after the other. Values ​​-1 may correspond to an arbitrary positive integer and the values ai > 0 must be equal to the corresponding elements of sought consecutive record of the progressions.

Let us remind you that a finite sequence c is called an arithmetic progression if the difference ci + 1 - ci of any two consecutive elements in it is constant. By definition, any sequence of length 1 is an arithmetic progression.

Input

The first line of the input contains integer n (1 ≤ n ≤ 2·105) — the number of elements in the sequence. The second line contains integer values a1, a2, ..., an separated by a space (1 ≤ ai ≤ 109 or ai =  - 1).

Output

Print the minimum number of arithmetic progressions that you need to write one after another to get sequence a. The positions marked as -1 in a can be represented by any positive integers.

Sample test(s)
input
98 6 4 2 1 4 7 10 2
output
3
input
9-1 6 -1 2 -1 4 7 -1 2
output
3
input
5-1 -1 -1 -1 -1
output
1
input
7-1 -1 4 5 1 2 3
output
2

题目大意:

        给出n个数的数列,要求将其划分成若干个等差数列,并且要求划分出来的个数最小


解法:

        贪心+模拟;我们只需要局部保证某个数列最长就够了.

        模拟的时候略微麻烦.

        首先我们想,一个等差数列,需要确认一个首项和公差,首项在本题中貌似无法很好确认,那么我们只需要确认公差和数列中的一个数就够了.这样我们就可以以这个数为中心,左右拓展开来,让每个数列尽量长度最大,就可以保证划分出来的个数最小.

         由于"-1"的存在,使得我们寻找公差和某项的困难加大了一点,但是也是可以找到了.

         由于"-1"可以成为任意一个正整数,所以暂时无须理会,因为如果存在确定数字的话,"-1"是需要看确定数字的情况来决定的.

         每次寻找数列,就需要进行如下操作:

                 ans++;既然还可以继续寻找数列,那么就必然存在一个,接下来我们只需要确认数列中止的地方head-1,并且下一次从中止的地方head开始(head初始为1)

                 先找到2个确定数字, 位置为i1和i2. 如若找不到2个确定数字,则可以确定已经走到数列尽头;中止地方为n;

                 然后确定公差,如若无法确定公差,(a[i1]-a[i2])%(i1-i2) != 0, 表明这两个确定数字不可能在同一个数列中,中止的地方为i2-1; 由于可以使得公差为0,那么在head~i2-1之间的数字都可以变为跟地一个确定数字一样,成为一个等差数列.

                  可以确定公差之后,计算在head~i1之间的"-1",是否可以满足该公差的关系,例如: -1 -1 1 2. 这个序列,前面的-1是无法满足正整数这个条件的.

                          所以如若不能满足,则按照无法确定公差的情况处理,中止地方为i2-1(每个数列长度最大化原则);

                          如若可以满足,则向右拓展,判断拓展的数字是否满足该等差数列要求,即 a[i2] + d*(i3-i2)  i3为当前数字的位置. 一直拓展到某个数字不符合或者是n为止.


代码:

#include <cstdio>__int64 n;__int64 a[200010];void init() {scanf("%I64d", &n);for (__int64 i = 1; i <= n; i++)  scanf("%I64d", &a[i]);}__int64 check(__int64 f) {for (__int64 i = f; i <= n; i++)if (a[i] != -1)  return(i);return(n+1);}__int64 dfs(__int64 head) {__int64 i1=check(head);__int64 i2=check(i1+1);if (i1 > n || i2 > n)  return(n+1);if ((a[i2]-a[i1])%(i2-i1) != 0)  return(i2);__int64 d = (a[i2]-a[i1])/(i2-i1);if (a[i1]-d*(i1-head) < 1)  return(i2);__int64 sum = a[i2];__int64 i;for (i = i2+1; i <= n; i++) {sum += d;if (sum < 1)  return(i);if (a[i] != -1 && a[i] != sum)  return(i);}return(i);}void solve() {__int64 head = 1, ans = 0; while (head <= n) {ans++;head = dfs(head);}printf("%I64d", ans);}int main() {init();solve();}







        



0 0
原创粉丝点击