Alice and Bob are playing a simple game. They line up a row of n identical coins, all with the heads facing down onto the table and the tails upward.
For exactly mm times they select any k of the coins and toss them into the air, replacing each of them either heads-up or heads-down with the same possibility. Their purpose is to gain as many coins heads-up as they can.
Input
The input has several test cases and the first line contains the integer t(1≤t≤1000) which is the total number of cases.
For each case, a line contains three space-separated integers n, m1≤n,m≤100) and k (1≤k≤n).
Output
For each test case, output the expected number of coins heads-up which you could have at the end under the optimal strategy, as a real number with the precision of 33 digits.
样例输入
6 2 1 1 2 3 1 5 4 3 6 2 3 6 100 1 6 100 2
样例输出
0.500 1.250 3.479 3.000 5.500 5.000
题目来源
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 #include <vector> 6 #include <queue> 7 #include <set> 8 #include <map> 9 #include <string> 10 #include <cmath> 11 #include <cstdlib> 12 #include <ctime> 13 using namespace std; 14 typedef long long ll; 15 int t,n,m,k; 16 const int N=110; 17 double dp[N][N]; 18 double c[N][N];//ll也会爆,一定要写成double 19 double p[N]; 20 double ans; 21 void C() 22 { 23 c[0][0]=1; 24 for(int i=1;i<=100;i++) 25 { 26 for(int j=0;j<=i;j++) 27 { 28 if(j==0||j==i) c[i][j]=1; 29 else { 30 c[i][j]=c[i-1][j-1]+c[i-1][j]; 31 } 32 } 33 } 34 p[0]=1; 35 for(int i=1;i<=100;i++) p[i]=p[i-1]/2; 36 } 37 int main() 38 { 39 scanf("%d",&t); 40 C(); 41 /* 42 for(int i=1;i<=100;i++) 43 { printf("%dllll\n",i); 44 for(int j=0;j<=i;j++) 45 { 46 printf("%d%c",c[i][j],j==i?'\n':' '); 47 } 48 //c[33][j]就爆int 了。 49 } 50 */ 51 while(t--) 52 { 53 scanf("%d%d%d",&n,&m,&k); 54 memset(dp,0,sizeof(dp)); 55 //dp[i][j]: i次操作后,正面朝上的面数为j的概率 56 dp[0][0]=1;//初始都是反面 57 for(int i=0;i<m;i++) 58 { 59 for(int j=0;j<=n;j++) 60 { 61 for(int l=0;l<=k;l++)//取得k个里面l个正面朝上。 62 { //反面的个数大于k,直接从反面的里面取k个 63 if((n-j)>=k) dp[i+1][j+l]+=dp[i][j]*c[k][l]*p[k];//取出的K个硬币每个的结果概率都是1/2(正/反) 64 //反面的个数小于k,只能再从已经是正面的里面再取出k-(n-j)个。 65 else dp[i+1][j-(k-(n-j))+l]+=dp[i][j]*c[k][l]*p[k]; 66 } 67 } 68 } 69 ans=0; 70 for(int i=1;i<=n;i++)ans+=i*dp[m][i];//期望,别忘了*i 71 printf("%.3f\n",ans); 72 } 73 return 0; 74 }