CodeForces 416D (贪心)

Problem Population Size

题目大意

  给一个长度为n的序列,由 -1 和正整数组成,-1表示任意的正整数。

  将序列分成若干段,使得任意段都是等差数列,求最少段数。

解题分析

  可以发现对于某一段序列,越长越好。贪心加点,保证每段都是最长就可以了。

  Tips:一段相同的数也可以算是等差数列。

参考程序

  1 #include <map>
  2 #include <set>
  3 #include <stack>
  4 #include <queue>
  5 #include <cmath>
  6 #include <ctime>
  7 #include <string>
  8 #include <vector>
  9 #include <cstdio>
 10 #include <cstdlib>
 11 #include <cstring>
 12 #include <cassert>
 13 #include <iostream>
 14 #include <algorithm>
 15 #pragma comment(linker,"/STACK:102400000,102400000")
 16 using namespace std;
 17 
 18 #define N 200008             
 19 #define M 50008    
 20 #define LL long long
 21 #define lson l,m,rt<<1
 22 #define rson m,r+1,rt<<1|1 
 23 #define clr(x,v) memset(x,v,sizeof(x));
 24 const int mo  = 1000000007;
 25 const int inf = 0x3f3f3f3f;
 26 const int INF = 2000000000;
 27 /**************************************************************************/ 
 28 int n;
 29 int a[N],r[N];
 30 
 31 int main(){
 32     scanf("%d",&n);
 33     for (int i=1;i<=n;i++) scanf("%d",&a[i]);
 34     int x=n+1;
 35     for (int i=n;i>=1;i--){
 36         r[i]=x;
 37         if (~a[i]) x=i;
 38     }
 39 
 40     int i=1,j,k,d,num1,num2,ans=0;
 41     
 42     while (i<=n){
 43         //printf("%d\n",i );
 44         if (a[i]==-1){
 45             j=r[i]; k=r[j];
 46             if (j==n+1) { ans++; break; } else num1=j-i; 
 47             num2=k-j;
 48             if (k==n+1){
 49                 /*if (min(num1,num2)>=a[j]) { ans+=2; break; } 
 50                     else { ans++; break; }
 51             */
 52                 ans++; break;
 53             }
 54             else{
 55                 int flag=0;
 56                 if ( (a[k]-a[j]) % (k-j)==0){
 57                     d=(a[k]-a[j]) / (k-j);
 58                     if ( 1ll*a[j] - 1ll*d * (j-i) > 0 ) flag =1;
 59                 }
 60                 if (flag){
 61                     long long x=a[k];
 62                     for (i=k+1;i<=n;i++){
 63                         x+=d;
 64                         if (x<=0) break;
 65                         if (a[i]!=-1 && a[i]!=x) break;
 66                     }
 67                     ans++;
 68                 }
 69                 else{
 70                     /*if (min(num1,num2)>=a[j]) i=j+a[j];  else i=k;*/
 71                     ans++; i=k;
 72                 }
 73             }
 74         }
 75         else
 76         {
 77             j=r[i];
 78             if (j==n+1) { ans++; break; } else num1=j-i-1; 
 79             
 80             int flag=0;
 81             if ( (a[j]-a[i]) % (j-i)==0){
 82                 d=(a[j]-a[i]) / (j-i);
 83                 flag =1;
 84             }
 85             if (flag){
 86                 long long x=a[j];
 87                 for (i=j+1;i<=n;i++){
 88                     x+=d;
 89                     if (x<=0) break;
 90                     if (a[i]!=-1 && a[i]!=x) break;
 91                 }
 92                 ans++;
 93             }
 94             else{
 95                 i=j;
 96                 ans++;
 97             }
 98         }
 99     }
100     printf("%d\n",ans);
101 }
View Code

 

posted @ 2016-08-15 17:23  rpSebastian  阅读(376)  评论(0编辑  收藏  举报