[USACO19FEB]Cow Dating P 題解
阿新 • • 發佈:2021-10-15
link
此為 CF442B Andrey and Problem 的弱化版。
(此為選數只留下一個算最大/最小概率此類題型的板子。。)
考慮 dp,易寫出轉移式:\(dp[i]=\prod (1-a_j)_{j<i}\times a_i+dp[i-1]\times (1-a_i)\)。
考慮當前我們是否要轉移,即 \(dp[i]>dp[i-1]\)。
\(\prod (1-a_j)_{j<i}\times a_i+dp[i-1]\times (1-a_i)>dp[i-1]\)
\(=>\prod (1-a_j)^{j<i}>dp[i-1]\)。
多麼美妙!但考慮 \(dp[i-1]\)
根據其定義,我們可以知道:
\(dp[i-1]=\sum_{j=1}^{i-1} a_j /(1-a_j)\prod (1-a_k)\)
好的,兩邊約掉,得 \(\sum_{j=1}^{i-1} \frac {a_j} {1-a_j}<1\)。
固定左端點,肯定要右端點越遠越好,二分即可。
#include <cstdio> #include <algorithm> #include <cmath> #include <cstring> #include <iostream> #define LL long long using namespace std; #define Debug(x) cerr << #x << ' ' << x #define hh cerr << endl const int MAXN = 1e6 + 5; int n; long double a[MAXN], pre[MAXN], tmp[MAXN], maxx; int main() { scanf("%d", &n); tmp[0] = 1; for(int i = 1; i <= n; i ++) scanf("%Lf", &a[i]), a[i] /= 1000000; for(int i = 1; i <= n; i ++) { pre[i] = pre[i - 1] + a[i] / (1 - a[i]); tmp[i] = tmp[i - 1] * (1 - a[i]); } for(int i = 1; i <= n; i ++) { int t = lower_bound(pre + i, pre + 1 + n, 1 + pre[i - 1]) - pre; t = min(t, n); maxx = max(maxx, (pre[t] - pre[i - 1]) * tmp[t] / tmp[i - 1]); } printf("%d", (int)floor(maxx * 1e6)); return 0; }