5212: Coins I
时间限制: 1 Sec 内存限制: 128 MB
提交: 122 解决: 74
[提交] [状态] [讨论版] [命题人:admin]
题目描述
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 m 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.
输入
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, m (1 ≤ n, m ≤ 100) and k (1 ≤ k ≤ n).
输出
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 3 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
#include<bits/stdc++.h>
using namespace std;
#define IO ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define rep(i,j,k) for(int i=j;i<k;i++)
#define per(i,j,k) for(int i=j;i<=k;i++)
const int maxn = 101;
typedef long long ll;
double c[maxn][maxn]; //与double组合运算必须要是双精度类型! int/float WA
double dp[maxn][maxn];
void init()
{
c[0][0]=1;
per(i,1,100)
{
c[i][0]=1;
per(j,1,i)
c[i][j] = c[i-1][j]+c[i-1][j-1];
}
/*
p[0] = 1;
per(i,1,100) p[i] = p[i-1]/2;
*/
}
int main(void)
{
IO
init();//组合数打表
int T;
cin>>T;
while(T--)
{
int n,m,k;
cin>>n>>m>>k;
double pp = pow(2.0,k); //一次(m)操作有2^k种情况
memset(dp,0,sizeof(dp));
dp[0][0] = 1;
rep(i,0,m)
{
per(j,0,n)
{
if(dp[i][j]==0) continue;
per(t,0,k)
{
if(n-j>=k) dp[i+1][j+t] += dp[i][j]*c[k][t]/pp;
else dp[i+1][j-(k-(n-j))+t] += dp[i][j]*c[k][t]/pp; //j目前正面硬币数
//k-(n-j) 额外需要翻的正面硬币数
//j-(k-(n-j))+0 ~ j-(k-(n-j))+k j个正面的基础上得到翻k个硬币正面的机会依旧!
}
}
}
double ans = 0.0;
per(i,1,n) ans += dp[m][i]*i;
cout<<setiosflags(ios::fixed)<<setprecision(3)<<ans<<endl;
}
}