[USACO19FEB]Cow Dating P 题解

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;
}

posted @ 2021-10-15 19:15  Saintex  阅读(43)  评论(0编辑  收藏  举报