題目鏈接:http://codeforces.com/problemset/problem/513/C
題意:有n個公司,他們要競標一個廣告位,他們出的錢的金額在L[i]到R[i]之間,問你所有公司所出的錢中第二高的金額的期望值。(2 <= n <= 5 ,1 <= L[i],R[i] <=10000)
目前碰到概率和期望的題目簡直毫無思路啊。。。現在的能力只能去硬着頭皮看題解(感覺能徹懂題解都不錯了。。)
解法(參考tourist的代碼):可以用很暴力的方法來做,首先枚舉第二高的金額(1~10000),然後枚舉所有公司有哪幾個公司出的錢達到了當前枚舉的第二高金額(狀態壓縮,0表示該公司沒達到,1表示達到了),如果達到的公司小於兩個就跳出把,應爲1個公司不管出多少錢都是第一高的金額。之後判斷每個公司達到和不達到的狀態。對於所有的公司而言,他們所能出的錢和當前枚舉的金額(now)只有這3種狀態,L <= R <= now,L <= now <= R,now <= L <= R。
對於達到第二高金額的公司,若L <= now,那麼概率爲(R - now + 1) / (R - L + 1),因爲只考慮會出現第二高金額的部分嘛;對於未達到第二高金額的公司,若R > now - 1,那麼概率爲(now - 1 - L + 1) / (R - L + 1),因爲要保證這個公司不會達到第二高金額;最後將所有的概率都加起來就是最後的答案了(這裏不懂,爲什麼全部加起來就是期望了,期望不是 概率 * 值 嗎。。。)
#include<bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const int maxn = 55;
int L[maxn],R[maxn];
int main()
{
int n;
while(~scanf("%d",&n))
{
double sum = 0;
for(int i = 0;i < n;i++)scanf("%d%d",L + i,R + i);
for(int now = 1;now <= 10010;now++)
{
for(int sta = 0;sta < (1 << n);sta++)
{
int cnt_1 = 0;
for(int i = 0;i < n;i++)
if(sta & (1 << i))
cnt_1++;
if(cnt_1 < 2)continue;
double res = 1.0;
for(int i = 0;i < n;i++)
{
int l = L[i];
int r = R[i];
double pro = 1.0;
if(sta & (1 << i)){//對於達到第二高金額的公司
if(l < now)l = now;
}else{//對於未達到第二高金額的公司
if(r > now - 1) r = now - 1;
}
if(l > r)//這種情況不可能的,break
{
res = 0.0;break;
}
int cur = r - l + 1;
res *= 1.0 * cur / (R[i] - L[i] + 1);
}
sum += res;
}
}
printf("%.15lf\n",sum);
}
}