D. Two Pirates - 2
Two pirates are dividing looted treasures. There are nn treasures, the ii-th of which costs aiai gold. They move in rotation, each turn a pirate picks one of the remaining treasures. The thing is, the second pirate is drunk, so he doesn't make optimal picks and each turn just picks a random available treasure, uniformly. The first pirate knows that and always makes optimal picks.
Find the expected costs of treasures picked by both pirates.
InputThe first line contains an integer nn (1≤n≤5000) — the number of treasures.
The second line contains nn integers aiai(1≤ai≤109)— the costs of the treasures.
OutputOutput two floating-point numbers: the expected costs of treasures picked by the first and the second pirates.
The absolute or relative error of the numbers shouldn't exceed 10−910−9.
Examples input Copy2output Copy
1 3
3.000000000000000 1.000000000000000input Copy
3output Copy
2 1 4
5.500000000000000 1.500000000000000
题目描述:
有n个价值为a[i]的宝藏,清醒的海盗和喝醉的海盗轮流拿。清醒的海盗总是会拿价值最大的宝藏,喝醉的海盗则会随机挑一个剩下的,问两个海盗获得宝藏总价值的期望。
分析:(下面是官方题解)
大概的意思就是,先把宝藏价值从小到大排序,按正常来说,清醒海盗每次都拿最大价值的也就是最后一个,醉海盗则是随机拿。
现在把他反过来想,在空箱子中从小到大轮流放球,清醒海盗放的球为黑色,醉海盗为白色,第i个球为黑色表示清醒海盗拿了第i个宝藏。
dp[i][j]表示已经放了i个球,从左数第j个球为黑色的概率。
当清醒海盗放球时,转移为dp[i+1][j]=dp[i][j] (j<i+1)。dp[i+1][i+1]=1。因为清醒海盗必定选最后一个,也就是把黑球放在最右边。
当醉海盗放球时,dp[i+1][j]=(j-1)/(i+1) * dp[i][j-1] + (i+1-j)/(i+1) * dp[i][j],对应醉海盗把白球放左边时,会使原来在j-1位置的球到达j位置。把白球放右边时,j位置的球还是在j位置。
关于谁先放与宝藏数量的奇偶有关,当为奇数时,因为清醒海盗会多拿一个,所以肯定要先手。当为偶数时,因为先放拿到的价值最小,所以要醉海盗先放。
最后答案就是dp[n][i] * a[i]的总和。
代码:
#include<cstdio> #include<iostream> #include<deque> #include<cstring> #include<cmath> #include<map> #include<vector> #include<bits/stdc++.h> #define sd(x) scanf("%d",&x) #define lsd(x) scanf("%lld",&x) #define sf(x) scanf("%lf",&x) #define ms(x,y) memset(x,y,sizeof x) #define fu(i,a,b) for(int i=a;i<=b;i++) #define fd(i,a,b) for(int i=a;i>=b;i--) #define all(a) a.begin(),a.end() #define range(a,x,y) a+x,a+y+x using namespace std; using namespace __gnu_cxx; typedef long long ll; typedef unsigned long long ull; typedef long double ld; typedef pair<char,int> P; const int N=5e3+99; ll mod=2147493647; const int INF=1e9+7; int a[N],n; double dp[N][N]; int main() { sd(n); fu(i,1,n) { sd(a[i]); } sort(a+1,a+n+1); bool fmove=n%2;//偶数个的话,醉海盗先放,奇数个的话清醒海盗先放 fu(i,1,n) { fu(j,1,n) { if(fmove) { //清醒海盗 if(i==j) dp[i][j]=1; else dp[i][j]=dp[i-1][j]; } else { //醉海盗 double lp=(j-1)*1.0/i,rp=(i-j)*1.0/i; dp[i][j]=dp[i-1][j-1]*lp+dp[i-1][j]*rp; } } fmove^=1; } double ans1=0,ans2=0; fu(i,1,n) { ans1+=dp[n][i]*a[i];//清醒海盗拿的 ans2+=(1-dp[n][i])*a[i];//醉海盗拿的 } printf("%.15f %.15f\n",ans1,ans2); return 0; }
Two pirates are dividing looted treasures. There are nn treasures, the ii-th of which costs aiai gold. They move in rotation, each turn a pirate picks one of the remaining treasures. The thing is, the second pirate is drunk, so he doesn't make optimal picks and each turn just picks a random available treasure, uniformly. The first pirate knows that and always makes optimal picks.
Find the expected costs of treasures picked by both pirates.
InputThe first line contains an integer nn (1≤n≤50001≤n≤5000) — the number of treasures.
The second line contains nn integers aiai (1≤ai≤1091≤ai≤109) — the costs of the treasures.
OutputOutput two floating-point numbers: the expected costs of treasures picked by the first and the second pirates.
The absolute or relative error of the numbers shouldn't exceed 10−910−9.
Examples input Copy2output Copy
1 3
3.000000000000000 1.000000000000000input Copy
3output Copy
2 1 4
5.500000000000000 1.500000000000000