題意簡述
Bessie要找 頭奶牛約會,第 頭奶牛同意的概率是 。Bessie 會對一個連續區間的所有奶牛邀請約會,但是她只希望恰好一個同意來約會。請求出所有區間中,恰好只有一個奶牛同意約會的概率的最大值。輸出這個最大的概率乘以 後下取整的結果。
,。
思路框架
設 ,。
一段區間 中只有恰好一個奶牛同意邀請的概率爲: 設 ,那麼這個概率爲
(設 )
證明一下單調性,就珂以 做了。
具體思路
我們考慮從 變成 會怎麼樣。
的答案是 。
而 變成 的時候, 新乘了一個 , 新加了一個 。答案變成:
假設這個答案比 的答案優,那麼
簡單移項發現:
那麼對於每個 ,我們找到一個最大的 滿足 ,那麼 就是以 爲左端點的最優解了。而隨着 的增大, 值顯然會減小,那麼 就會不斷往右移(或者不變)。這就是單調性,利用這單調性,珂以輕鬆的 求解。
代碼
#include <bits/stdc++.h>
using namespace std;
namespace Flandre_Scarlet
{
#define N 1666666
#define real double
#define F(i,l,r) for(int i=l;i<=r;++i)
#define D(i,r,l) for(int i=r;i>=l;--i)
#define Fs(i,l,r,c) for(int i=l;i<=r;c)
#define Ds(i,r,l,c) for(int i=r;i>=l;c)
#define MEM(x,a) memset(x,a,sizeof(x))
#define FK(x) MEM(x,0)
#define Tra(i,u) for(int i=G.Start(u),__v=G.To(i);~i;i=G.Next(i),__v=G.To(i))
#define p_b push_back
#define sz(a) ((int)a.size())
#define iter(a,p) (a.begin()+p)
void R1(int &x)
{
x=0;char c=getchar();int f=1;
while(c<'0' or c>'9') f=(c=='-')?-1:1,c=getchar();
while(c>='0' and c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
x=(f==1)?x:-x;
}
void Rd(int cnt,...)
{
va_list args;
va_start(args,cnt);
F(i,1,cnt)
{
int* x=va_arg(args,int*);R1(*x);
}
va_end(args);
}
int n;
real p[N];
void Input()
{
R1(n);
F(i,1,n) {scanf("%lf",&p[i]); p[i]/=1e6;}
}
real a[N],b[N];
void Soviet()
{
F(i,1,n) a[i]=1.0-p[i],b[i]=p[i]/(1.0-p[i]);
//計算出a,b
int p=0;
//p維護滿足條件的最大的r值
real A=1.0,B=0.0;
//一定注意!A的初始值爲1!
real ans=0.0;
F(i,1,n)
{
while(p<n and B<1.0) ++p,A*=a[p],B+=b[p];
//此時p是最大的滿足B<1的值+1
ans=max(ans,A*B);
//那麼A*B就是以i爲左端點的最優解了
A/=a[i]; B-=b[i];
}
printf("%d\n",(int)(ans*1e6));
}
#define Flan void
Flan IsMyWife()
{
Input();
Soviet();
}
}
int main()
{
Flandre_Scarlet::IsMyWife();
getchar();getchar();
return 0;
}