UESTC 1015 Lweb and pepper --前,后缀最值
题意: n种食物,每种含花椒的概率为Pi,现在已经选择了[L,R]这个区间(下标)的食物,要再选一个,使总的食物只有一种含花椒的概率最大,问选哪个最好,相同的选下标小的。
解法: 就不写解法了。此处有官方题解: http://acm.uestc.edu.cn/bbs/read.php?tid=5835
维护一个前缀后缀的最值即可。
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <algorithm> #define Mod 1000000007 #define eps 1e-8 using namespace std; #define N 100002 int preMax[N],bacMax[N],preMin[N],bacMin[N]; double pMax[N],pMin[N],bMax[N],bMin[N],p[N]; int sgn(double x) { if(x < -eps) return -1; if(x > eps) return 1; return 0; } int main() { int t,n,i,m,L,R; cin>>t; while(t--) { scanf("%d",&n); for(i=1;i<=n;i++) scanf("%lf",&p[i]); preMax[0] = 0; preMin[0] = 0; pMax[0] = -1; pMin[0] = Mod; bacMax[n+1] = n+1; bacMin[n+1] = n+1; bMax[n+1] = -1; bMin[n+1] = Mod; for(i=1;i<=n;i++) { preMax[i] = preMax[i-1]; preMin[i] = preMin[i-1]; pMax[i] = pMax[i-1]; pMin[i] = pMin[i-1]; if(p[i] > pMax[i]) pMax[i] = p[i], preMax[i] = i; if(p[i] < pMin[i]) pMin[i] = p[i], preMin[i] = i; } for(i=n;i>=1;i--) { bacMax[i] = bacMax[i+1]; bacMin[i] = bacMin[i+1]; bMax[i] = bMax[i+1]; bMin[i] = bMin[i+1]; if(p[i] >= bMax[i]) bMax[i] = p[i], bacMax[i] = i; if(p[i] <= bMin[i]) bMin[i] = p[i], bacMin[i] = i; } scanf("%d",&m); while(m--) { scanf("%d%d",&L,&R); L++,R++; double B = 1.0, E = 0.0; for(i=L;i<=R;i++) B *= (1-p[i]), E += p[i]/(1-p[i]); if(sgn(1-E) > 0) { if(pMax[L-1] >= bMax[R+1]) printf("%d\n",preMax[L-1]-1); else printf("%d\n",bacMax[R+1]-1); } else { if(pMin[L-1] <= bMin[R+1]) printf("%d\n",preMin[L-1]-1); else printf("%d\n",bacMin[R+1]-1); } } } return 0; }
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。