题目大意就是在给出的串中找出一段连续数字,使得 这一段的和 乘上 这一段最小的数 的结果最大。
可以用rmq做。每次区间找当中最小的数,算出值并记录位置。然后再递推它的左右区间。
不过- -,一开始用深搜递推RE了。栈空间不够了,然后慢慢优化,最后还是ac了。
貌似这一题是用单调栈做的,还可以用查并集做。。。我也是醉了
具体看代码吧
1 /************************************************************************* 2 > File Name: c.cpp 3 > Author: milaso 4 > Mail: [email protected] 5 > Created Time: 2014年07月21日 星期一 21时18分40秒 6 ************************************************************************/ 7 //#pragma comment(linker, "/STACK:1024000000,1024000000") 8 //如果自己电脑上100000的数据过的了,但是oj RE 那就加上上面的代码 9 #include<iostream> 10 #include<math.h> 11 #include<algorithm> 12 #include<string.h> 13 #include<string> 14 #include<stdio.h> 15 #include<fstream> 16 using namespace std; 17 18 int num[100010]; 19 long long sum[100010]; 20 int pos[100010][17]; // 最好只开17吧,不然可能RE 21 int n; 22 23 struct node{ 24 long long ans; 25 int l,r; 26 }; 27 28 29 void rmq_ini(){ 30 for(int i=1;i<=n;i++) pos[i][0] =i; 31 for(int j=1;(1<<j) <=n;j++) 32 for(int i=1;(i+(1<<j)-1) <= n;i++ ){ 33 if(num[pos[i][j-1]] < num [pos[i+(1<<(j-1))][j-1]]){ 34 pos[i][j] = pos[i][j-1]; 35 } 36 else 37 pos[i][j] = pos[i+(1<<(j-1))][j-1]; 38 } 39 } 40 41 int rmq(int l,int r){ 42 int k=0; 43 while((2<<k) <=(r-l+1)) k++; 44 if(num[pos[l][k]] < num[pos[r-(1<<k)+1][k]]) 45 return pos[l][k]; 46 else 47 return pos[r-(1<<k)+1][k]; 48 } 49 50 51 node dfs(int l,int r){ // !!!!!!!!!最好只用两个node,不然会RE 52 node a; 53 if( l == r) { 54 a.ans=0; 55 a.l = l; 56 a.r = r; 57 return a; 58 } 59 if (l+1 == r){ 60 a.ans=(long long )num[r]* (long long )num[r]; 61 a.l = l; 62 a.r = r; 63 return a; 64 } 65 int m=rmq(l+1,r); 66 node an; 67 an.ans=(sum[r]-sum[l])*num[m];an.l=l;an.r=r; 68 a = dfs(l,m-1); 69 if(a.ans > an.ans){ 70 an.ans= a.ans; 71 an.l=a.l;an.r=a.r; 72 } 73 a =dfs(m,r); 74 if(a.ans > an.ans){ 75 an.ans =a.ans; 76 an.l=a.l;an.r=a.r; 77 } 78 return an; 79 } 80 81 82 83 int main(){ 84 scanf("%d",&n); 85 for(int i=1;i<=n;i++){ 86 scanf("%d",&num[i]); 87 sum[i] = sum[i-1] + num[i]; 88 } 89 rmq_ini(); 90 node ans=dfs(0,n); 91 //long long ans=dfs(0,n); 92 //cout<<ans<<endl; 93 cout<<ans.ans<<endl<<ans.l + 1<<" "<<ans.r<<endl; //l要加一哦 94 return 0; 95 }
Feel Good (poj 2796)
时间: 2024-10-12 08:46:00