hdoj 3486 预处理区间最大值然后枚举

题目链接http://acm.hdu.edu.cn/showproblem.php?pid=3486

解析  事先预处理了区间的最大值。。加了点小优化。算出了最少需要几组。。然后暴力枚举水过

ac代码

  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<math.h>
  4 #include<stdlib.h>
  5 #define maxn 200010
  6 int num[maxn];
  7 int Log[maxn];
  8 int n, maxnum;
  9 int dp[22][maxn];
 10 int max(int a,int b)
 11 {
 12     if(a>b)
 13       return a;
 14     return b;  
 15 }
 16 void Init_rmq()
 17 {
 18 
 19     int i, j;
 20     for(i=1;i<=n;i++)
 21     {
 22         dp[0][i]=num[i];
 23     }
 24    
 25     for( i = 1; i <= n ; i ++) dp[0][i] = num[i];   
 26     for(i = 1; i <= Log[n] ; i ++) {   
 27         int limit = n - (1<<i) + 1;   
 28         for( j = 1; j <= limit ; j ++) {   
 29             dp[i][j] = max(dp[i-1][j] , dp[i-1][j+(1<<(i-1))]);   
 30         }   
 31     }   
 32 
 33 
 34 }
 35 
 36 int query(int a,int b,int k)
 37 {
 38    
 39     
 40     return max(dp[k][a],dp[k][b-(1<<k)+1]);
 41 }
 42 
 43 
 44 int main()
 45 {
 46     int i;
 47     memset(Log,0,sizeof(Log));
 48     for(i=1;i<=maxn;i++)
 49     {
 50         if((i&(i-1))==0)
 51         {
 52             Log[i]=Log[i-1]+1;
 53         }
 54         else
 55          Log[i]=Log[i-1];
 56     }
 57 
 58     while(scanf("%d %d",&n,&maxnum)!=EOF)
 59     {
 60         if(n==-1&&maxnum==-1)
 61           break;
 62         int i;
 63         int maxx=-1;
 64         int ss=0;
 65         for(i=1;i<=n;i++)
 66         {
 67             scanf("%d",&num[i]);
 68             if(maxx<num[i])
 69              maxx=num[i];
 70             ss+=num[i]; 
 71         }
 72         if(ss<=maxnum)
 73           {
 74            printf("-1\n");
 75              continue;
 76           }
 77         Init_rmq();  
 78        int j;
 79          if(maxx==0)
 80          maxx=1;
 81        int be = maxnum/maxx;
 82      
 83        if(be==0)
 84          be=1;
 85         for(i=be;i<=n;i++)
 86         {
 87             
 88             int sum=0;
 89             int d=n/i;
 90             int aten=1;
 91               for(j=1;j<=i;j++)
 92               {
 93                      
 94                      int k = log((double)d)/log(2.0);
 95                      sum+=query((j-1)*d+1,j*d,k);
 96                      
 97                      
 98                 }
 99                 if(sum>maxnum)
100                   break;
101         }
102          printf("%d\n",i);
103     }
104     return 0;
105 }

 

posted on 2012-10-20 16:11  acmer_acm  阅读(267)  评论(0编辑  收藏  举报