第 45 屆國際大學生程式設計競賽(ICPC)亞洲區域賽(南京)
阿新 • • 發佈:2021-10-31
思路:
由於是最優策略,所以並不是單純的求期望,而再分析下題目,說做一個煙花是n分鐘,放所有煙花是m分鐘,那對於最優策略我們可以求一個k,表示每製作k個煙花放一次,那麼每一輪時間花費就是k * n + m,由於成功的概率是p,所以失敗的概率是(1 - p),因此至少有一個成功的煙花的概率就是(1 - (1 - p) ^ k),顯然這是一個幾何分佈,所以期望就為1 /(1 - (1 - p) ^ k),表示進行了多少輪,再乘以每一輪的時間花費就是
(k * n + m) / (1 - (1 - p) ^ k)
求二階導可知這是一個單峰函式,所以可以三分出答案
然後就是要注意開long double,輸出long double 的時候是%Lf
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #include <cmath> #include <queue> #include <stack> #include <set> #include <vector> #include <map> #include <unordered_set> #include <unordered_map> #definex first #define y second #define IOS ios::sync_with_stdio(false);cin.tie(0); using namespace std; typedef long long LL; typedef pair<int, int> PII; const int N = 200010; const double PI = acos(-1); int n, m; long double p; long double f(int k)//(k*n+m) / (1-(1-p)^k) { return 1.0 * (k * n + m) / (1- pow(1 - p, k)); } int main() { IOS; int T = 1; cin >> T; while(T -- ) { cin >> n >> m >> p; p *= 1e-4; int l = 1, r = 0x3f3f3f3f; while(l < r) { int mid = l + (r - l) / 3, midmid = r - (r - l) / 3; if(f(mid) < f(midmid)) r = midmid - 1; else l = mid + 1; } printf("%.10Lf\n", f(l)); } return 0; }
思路:
題目中說找到一個c很具有迷惑性,其實具體思路就是在兩個b之間找到最多數量的a,我們可以用lower_bound來做,因此我們可以先排序,然後找出所有連續的兩個b之間的a的數量,但需要注意的是,我們還需要考慮第一個b之前是否有一些a和最後一個b之後是否有一些a,因此我們可以先在原b陣列增加兩個數,一個最小值一個最大值然後再找
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #include <cmath> #include <queue> #include <stack> #include <set> #include <vector> #include <map> #include <unordered_set> #include <unordered_map> #define x first #define y second #define IOS ios::sync_with_stdio(false);cin.tie(0); using namespace std; typedef long long LL; typedef pair<int, int> PII; const int N = 100010; const double PI = acos(-1); int a[N], b[N]; int main() { IOS; int T = 1; cin >> T; while(T -- ) { int n, m; cin >> n >> m; for (int i = 1; i <= n; i ++ ) cin >> a[i]; for (int i = 1; i <= m; i ++ ) cin >> b[i]; b[++m] = 0, b[++m] = 0x3f3f3f3f; sort(a + 1, a + 1 + n); sort(b + 1, b + 1 + m); int res = 0; for (int i = 1; i <= m; i ++ ) { int l = lower_bound(a + 1, a + 1 + n, b[i] + 1) - a;//下標 int r = lower_bound(a + 1, a + 1 + n, b[i + 1]) - a;//下標 res = max(res, r - l); } if(res > 0) cout << res << endl; else cout << "Impossible" << endl; } return 0; }