hdu 6693(19年杭电多校赛第十场第三题 (选择1-n个物品,求最大期望值))

Valentine’s Day
Time Limit: 2000/2000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)
Total Submission(s): 171 Accepted Submission(s): 83
Special Judge

Problem Description
Oipotato loves his girlfriend very much. Since Valentine’s Day is coming, he decides to buy some presents for her.

There are n presents in the shop, and Oipotato can choose to buy some of them. We know that his girlfriend will possibly feel extremely happy if she receives a present. Therefore, if Oipotato gives k presents to his girlfriend, she has k chances to feel extremely happy. However, Oipotato doesn’t want his girlfriend to feel extremely happy too many times for the gifts.

Formally, for each present i, it has a possibility of Pi to make Oipotato’s girlfriend feel extremely happy. Please help Oipotato decide what to buy and maximize the possibility that his girlfriend feels extremely happy for exactly one time.

Input
There are multiple test cases. The first line of the input contains an integer T (1≤T≤100), indicating the number of test cases. For each test case:

The first line contains an integer n (1≤n≤10 000), indicating the number of possible presents.

The second line contains n decimals Pi (0≤Pi≤1) with exactly six digits after the decimal point, indicating the possibility that Oipotato’s girlfriend feels extremely happy when receiving present i.

It is guaranteed that the sum of n in all test cases does not exceed 450000.

Output
For each test case output one line, indicating the answer. Your answer will be considered correct if and only if the absolute error of your answer is less than 10−6.

Sample Input
2
3
0.100000 0.200000 0.900000
3
0.100000 0.300000 0.800000

Sample Output
0.900000000000
0.800000000000
题意: 给出n个买当前物品令人开心的概率值,问从中买1-n个,从购买的全部中选出一个使其开心的最大概率值。
思路: 枚举购买1-n个物品的期望值,比如0.3 0.4 0.8这组数据中,买一个最大的开心值为0.8,买两个(从最大的两个中选)的为0.8*(1-0.4)+0.4*(1-0.8),买三个则为0.3*(1-0.4)(1-0.8)+(1-0.3)0.4(1-0.8)+(1-0.3)(1-0.4)*0.8,直接暴力求解即可,详情看代码和注释。

#include <bits/stdc++.h>
using namespace std;
const int N = 1e4 + 5;
double a[N];
int main() {
	int t, n;
	scanf("%d", &t);	
	while (t--) {
		double ans = 0.0, mul = 1.0, t = 0.0;
		scanf("%d", &n);
		for (int i = 0; i < n; i++) {
			scanf("%lf", &a[i]);
		}
		sort(a, a + n);
		if (a[n-1] == 1.0) ans = 1.0; // 对1的概率进行特判 
		else {
			for (int i = n - 1; i >= 0; i--) {
				mul *= (1.0 - a[i]); // 维护一个当前不选的概率积 
				t = 0.0;
				for (int j = i; j < n; j++) {
					// 得出选当前的和不选其他的概率值,即一遍for循环算出买了n-i个物品使其开心的期望值 
					t += (mul / (1 - a[j]) * a[j]);
				}
				if (t > ans) ans = t; 
				// 如果大于之前的最大值,更新,否则直接结束枚举;
				//选的越多,前面的开心概率越小,总的期望值会变小 
				else break;
			}
		}
		printf("%.12f\n", ans);
	}
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章