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 }