codeforces#253 D - Andrey and Problem裡的數學知識

weixin_34377065發表於2014-08-30

這道題是這種,給主人公一堆事件的成功概率,他僅僅想恰好成功一件。

於是,問題來了,他要選擇哪些事件去做,才幹使他的想法實現的概率最大。


我的第一個想法是列舉,列舉的話我想到用dfs,但是認為太麻煩。

於是想是不是有什麼規律,於是推導了一下,推了一個出來,寫成程式碼提交之後發現是錯的。

最後就沒辦法了,剩下的時間不夠寫dfs,於是就放棄了。


今天看thnkndblv的程式碼,程式碼非常短,於是就想肯定是有什麼數學規律,於是看了一下,

果然如此。


是這種,還是列舉,當然是有技巧的,看我娓娓道來。


列舉的話,如果總共同擁有n件事件,


從中選擇1件事情去做,實現的概率最大是多少,


選擇2件事情去做,實現的概率最大是多少,以此類推到選擇n件事情去做。


於是就會得到n個結果,裡面最大的那個就是實現主人公想法的最大概率。


這種話要從n件事件中隨意選出1件事情然後比概率,隨意選出2件事情然後比概率……隨意選出n件事情然後比概率


還是要搜尋。


可是這裡就有數學知識了,能夠不用搜尋,做法是這種:


將n個事件成功的概率從大到小排序,

然後,

僅僅選擇前1件事去做成功的概率就是“從中選擇1件事情去做,最大的實現概率”

僅僅選擇前2件事去做成功的概率就是“從中選擇2件事情去做,最大的實現概率”

以此類推。


有了這個,這道題就非常easy了,至於為什麼這樣做能夠,無法證明,假設有人證明的話,歡迎留言討論,附上原題以及地址和我後來AC的程式碼例如以下:

http://codeforces.com/contest/443/problem/D

D. Andrey and Problem
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Andrey needs one more problem to conduct a programming contest. He has n friends who are always willing to help. He can ask some of them to come up with a contest problem. Andrey knows one value for each of his fiends — the probability that this friend will come up with a problem if Andrey asks him.

Help Andrey choose people to ask. As he needs only one problem, Andrey is going to be really upset if no one comes up with a problem or if he gets more than one problem from his friends. You need to choose such a set of people that maximizes the chances of Andrey not getting upset.

Input

The first line contains a single integer n (1 ≤ n ≤ 100) — the number of Andrey's friends. The second line contains n real numbers pi (0.0 ≤ pi ≤ 1.0) — the probability that the i-th friend can come up with a problem. The probabilities are given with at most 6 digits after decimal point.

Output

Print a single real number — the probability that Andrey won't get upset at the optimal choice of friends. The answer will be considered valid if it differs from the correct one by at most 10 - 9.


#include<iostream>
#include<algorithm>
using namespace std;
bool cmp(double a,double b)
{
	return a>b;
}
int main()
{
	int n,i,j,k;
	double a[110],x,sum,MAX;
	scanf("%d",&n);
	for(i=0;i<n;i++)
		scanf("%lf",&a[i]);
	sort(a,a+n,cmp);
	MAX=0;
	for(i=1;i<=n;i++)
	{
		sum=0;
		for(j=0;j<i;j++)
		{
			x=a[j];
			for(k=0;k<i;k++)
			{
				if(j!=k)
					x*=1-a[k];
			}
			sum+=x;
		}
		MAX=max(sum,MAX);
	}
	printf("%.12lf\n",MAX);
}


相關文章