Piece of Cake 【概率/期望】

大體題意:給一個N個點的凸包,求任選K點組成的子凸包的面積期望怎麼做(3≤k≤n≤2500)

 

嘗試的掙扎:

1.暴力枚舉?顯然超時。

2.考慮新加入一個點對期望的貢獻?不會計算。

GG

 

正經題解:

被rqy秒了......

#include <bits/stdc++.h>
#define ll long long
#define rep(i, a, b) for(int i = (a); i <= (b); i++)
#define per(i, a, b) for(int i = (a); i >= (b); i--)
#define pii pair<int,int>
#define pdd pair<double,double>
#define all(x) (x).begin(),(x).end()
#define mp make_pair
#define pb push_back
#define ls (o<<1)
#define rs (o<<1|1)
#define mid (l+r>>1)
using namespace std;
const int N = 3000;
long double dp[N][N];      //精度需要用long double
long double C(int n,int m) {
    if(m>n) return 0;
    if(n<0||m<0) return 0;

    return dp[n+1][m+1];
}
pdd s[N];
double cs(int i,int j) {   //這裏在叉積裏直接取了負數
    return -(s[i].first*s[j].second-s[i].second*s[j].first);
}
int n,k;
int main() {
    int T;
    dp[0][0] = 1;
    rep(i, 1, 2501)
        rep(j, 1, i)
            dp[i][j] = dp[i-1][j-1]+dp[i-1][j];
    cin>>n>>k;
    rep(i, 1, n) cin>>s[i].first>>s[i].second;  //順時針給點
    double ans = 0;
    rep(i, 1, n) {
        rep(j, i+1, n) {
            if(i==j) continue;
            int num = abs(max(j,i)-min(j,i)+1);
            ans += cs(i,j)*C(n-num,k-2)/C(n,k);   //---ij----相鄰
            ans += cs(j,i)*C(num-2,k-2)/C(n,k);   //---ji----相鄰
        }
    }
    printf("%.10f",ans/2);
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章